public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* libstdc++/6513: severe regression from 3.0.x
@ 2002-04-30 18:28 Paolo Carlini
  0 siblings, 0 replies; only message in thread
From: Paolo Carlini @ 2002-04-30 18:28 UTC (permalink / raw)
  To: libstdc++; +Cc: bkoz, stephen, gcc

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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-05-01  0:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-04-30 18:28 libstdc++/6513: severe regression from 3.0.x Paolo Carlini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).