This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++/6513: severe regression from 3.0.x


Hi,

I'm trying to debug it a bit: it represents a very bad regression from 
3.0.x, possibly a release-critical one, IMHO. This is the testcase:

///////////////////////////////////
#include <vector>
#include <string>

using namespace std;

int main()
{
  const char* c_strings[5] = { "1", "2", "3", "4", "5" };
  vector<string> strings(c_strings, c_strings + 5);
  return 0;
}
////////////////////////////////////

We currently get a Segmentation fault. I have made some progress, but 
here in Italy is late at night, and I don't know how much I can do 
before tomorrow...

Where the execution of 3.0.4 and 3.1 pre start to diverge is in 
stl_uninitialized.h and precisely here:

3.0.4
-----
  72 template <class _InputIter, class _ForwardIter>
  73 inline _ForwardIter
  74 __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  75                          _ForwardIter __result,
  76                          __true_type)
  77 {
  78   return copy(__first, __last, __result);
  79 }
  80
  81 template <class _InputIter, class _ForwardIter>
  82 _ForwardIter
  83 __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  84                          _ForwardIter __result,
  85                          __false_type)
  86 {
  87   _ForwardIter __cur = __result;
  88   __STL_TRY {
  89     for ( ; __first != __last; ++__first, ++__cur)
  90       _Construct(&*__cur, *__first);
  91     return __cur;
  92   }
  93   __STL_UNWIND(_Destroy(__result, __cur));
  94 }
  95
  96
  97 template <class _InputIter, class _ForwardIter, class _Tp>
  98 inline _ForwardIter
  99 __uninitialized_copy(_InputIter __first, _InputIter __last,
 100                      _ForwardIter __result, _Tp*)
 101 {
 102   typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;
 103   return __uninitialized_copy_aux(__first, __last, __result, 
_Is_POD());
 104 }
 105
 106 template <class _InputIter, class _ForwardIter>
 107 inline _ForwardIter
 108   uninitialized_copy(_InputIter __first, _InputIter __last,
 109                      _ForwardIter __result)
 110 {
 111   return __uninitialized_copy(__first, __last, __result,
 112                               __value_type(__result));
 113 }
 114

3.1 pre
-------
  71   template<typename _InputIter, typename _ForwardIter>
  72     inline _ForwardIter
  73     __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  74                              _ForwardIter __result,
  75                              __true_type)
  76     { return copy(__first, __last, __result); }
  77
  78   template<typename _InputIter, typename _ForwardIter>
  79     _ForwardIter
  80     __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  81                              _ForwardIter __result,
  82                              __false_type)
  83     {
  84       _ForwardIter __cur = __result;
  85       try {
  86         for ( ; __first != __last; ++__first, ++__cur)
  87           _Construct(&*__cur, *__first);
  88         return __cur;
  89       }
  90       catch(...)
  91         {
  92           _Destroy(__result, __cur);
  93           __throw_exception_again;
  94         }
  95     }
  96
  97   /**
  98    *  @brief Copies the range [first,last) into result.
  99    *  @param  first  An input iterator.
 100    *  @param  last   An input iterator.
 101    *  @param  result An output iterator.
 102    *  @return   result + (first - last)
 103    *
 104    *  Like copy(), but does not require an initialized output range.
 105   */
 106   template<typename _InputIter, typename _ForwardIter>
 107     inline _ForwardIter
 108     uninitialized_copy(_InputIter __first, _InputIter __last, 
_ForwardIter __result)
 109     {
 110       typedef typename iterator_traits<_InputIter>::value_type 
_ValueType;
 111       typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
 112       return __uninitialized_copy_aux(__first, __last, __result, 
_Is_POD());
 113     }


That is, upon the uninitialized_copy call, in the case of 3.0.4 ends up 
being called

__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __false_type)

whereas for 3.1:

__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __true_type)

Indeed, it seems to me that /definitely/ a string is /not/ a POD, 
therefore the current code for some reason chooses the /wrong/ 
__uninitialized_copy_aux resulting in disaster. As you can see the code 
is overall quite different. I have found this relevant entry in the 
Changelog:

2001-07-17  Stephen M. Webb   <stephen@bregmasoft.com>r

        All occurrences of the __value_type() and __distance_type()
        functions, which were required to support the HP STL, have been
        removed along with all the auxiliary forwarding functions that
        were required to support their use.

Stephen, could you possibly help here?

I'm really worried since I suspect that beyond std::string other non-POD 
data types may give trouble at inizialization time for std::vector and 
for other containers. This would represent, IMHO, a release critical bug.

... now back to GDB...
Paolo.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]