
| Key: |
STDCXX-618
|
| Type: |
Bug
|
| Status: |
Open
|
| Priority: |
Minor
|
| Assignee: |
Unassigned
|
| Reporter: |
Travis Vitek
|
| Votes: |
0
|
| Watchers: |
0
|
|
If you were logged in you would be able to see more operations.
|
|
|
|
Time Tracking:
|
|
Original Estimate:
|
4h
|
|
|
Remaining Estimate:
|
4h
|
|
|
Time Spent:
|
Not Specified
|
|
|
|
| Severity: |
Incorrect Behavior
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
|
|
Description
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
|
Show » |
made changes - 24/Oct/07 10:54 PM
| Field |
Original Value |
New Value |
|
Attachment
|
|
21.string.append.log
[ 12368330
]
|
made changes - 24/Oct/07 11:10 PM
|
Description
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
|
|
Summary
|
purify free memory read in 21.string.append.cpp
|
purify reports free memory read in 21.string.append test
|
made changes - 21/Jan/08 06:33 PM
|
Remaining Estimate
|
|
4h
[ 14400
]
|
|
Original Estimate
|
|
4h
[ 14400
]
|
made changes - 01/Feb/08 04:35 AM
|
Assignee
|
|
Travis Vitek
[ vitek
]
|
made changes - 01/Feb/08 04:37 AM
|
Description
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
|
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
{noformat}
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
{noformat}
|
made changes - 23/Apr/08 08:39 PM
|
Fix Version/s
|
4.2.1
[ 12312690
]
|
|
|
Fix Version/s
|
|
4.2.2
[ 12313096
]
|
made changes - 11/Jul/09 12:00 AM
|
Assignee
|
Travis Vitek
[ vitek
]
|
|
|