This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[v3] c++/32158 (libstdc++ bits)


Hi,

tested x86-linux, committed to mainline.

Paolo.

////////////////
2007-05-31  Paolo Carlini  <pcarlini@suse.de>

	PR c++/32158 (libstdc++ bits)
	* include/bits/stl_uninitialized.h (__uninitialized_copy_aux,
	__uninitialized_fill_aux, __uninitialized_fill_n_aux):
	Remove.
	(struct __uninitialized_copy, struct __uninitialized_fill,
	struct __uninitialized_fill_n): Add.
	(uninitialized_copy, uninitialized_fill, uninitialized_fill_n):
	Adjust.
	* testsuite/20_util/specialized_algorithms/32158.cc: New.

	* include/bits/stl_uninitialized.h (uninitialized_copy(_InputIterator,
	_InputIterator, _ForwardIterator)): Robustify vs non-POD input.

	* include/bits/stl_vector.h (_M_fill_initialize): New.
	(vector(size_type, const value_type&, const allocator_type&),
	_M_initialize_dispatch(_Integer, _Integer, __true_type)): Use it.
	* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
	Adjust dg-error line.
	* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
	Likewise.
	* testsuite/23_containers/vector/requirements/dr438/
	constructor_1_neg.cc: Likewise.
	* testsuite/23_containers/vector/requirements/dr438/
	constructor_2_neg.cc: Likewise.
Index: include/bits/stl_vector.h
===================================================================
--- include/bits/stl_vector.h	(revision 125217)
+++ include/bits/stl_vector.h	(working copy)
@@ -210,11 +210,7 @@
       vector(size_type __n, const value_type& __value = value_type(),
 	     const allocator_type& __a = allocator_type())
       : _Base(__n, __a)
-      {
-	std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
-				      _M_get_Tp_allocator());
-	this->_M_impl._M_finish = this->_M_impl._M_start + __n;
-      }
+      { _M_fill_initialize(__n, __value); }
 
       /**
        *  @brief  %Vector copy constructor.
@@ -788,11 +784,7 @@
 	  this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n));
 	  this->_M_impl._M_end_of_storage =
 	    this->_M_impl._M_start + static_cast<size_type>(__n);
-	  std::__uninitialized_fill_n_a(this->_M_impl._M_start,
-					static_cast<size_type>(__n),
-					__value,
-					_M_get_Tp_allocator());
-	  this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
+	  _M_fill_initialize(static_cast<size_type>(__n), __value);
 	}
 
       // Called by the range constructor to implement [23.1.1]/9
@@ -831,7 +823,16 @@
 					_M_get_Tp_allocator());
 	}
 
+      // Called by the first initialize_dispatch above and by the
+      // vector(n,value,a) constructor.
+      _M_fill_initialize(size_type __n, const value_type& __value)
+      {
+	std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, 
+				      _M_get_Tp_allocator());
+	this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
+      }
 
+
       // Internal assign functions follow.  The *_aux functions do the actual
       // assignment work for the range versions.
 
Index: include/bits/stl_uninitialized.h
===================================================================
--- include/bits/stl_uninitialized.h	(revision 125217)
+++ include/bits/stl_uninitialized.h	(working copy)
@@ -64,26 +64,39 @@
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
-  template<typename _InputIterator, typename _ForwardIterator>
-    _ForwardIterator
-    __uninitialized_copy_aux(_InputIterator __first,
-			     _InputIterator __last,
-			     _ForwardIterator __result)
+  template<bool>
+    struct __uninitialized_copy
     {
-      _ForwardIterator __cur = __result;
-      try
-	{
-	  for (; __first != __last; ++__first, ++__cur)
-	    std::_Construct(&*__cur, *__first);
-	  return __cur;
+      template<typename _InputIterator, typename _ForwardIterator>
+        static _ForwardIterator
+        uninitialized_copy(_InputIterator __first, _InputIterator __last,
+			   _ForwardIterator __result)
+        {
+	  _ForwardIterator __cur = __result;
+	  try
+	    {
+	      for (; __first != __last; ++__first, ++__cur)
+		std::_Construct(&*__cur, *__first);
+	      return __cur;
+	    }
+	  catch(...)
+	    {
+	      std::_Destroy(__result, __cur);
+	      __throw_exception_again;
+	    }
 	}
-      catch(...)
-	{
-	  std::_Destroy(__result, __cur);
-	  __throw_exception_again;
-	}
-    }
+    };
 
+  template<>
+    struct __uninitialized_copy<true>
+    {
+      template<typename _InputIterator, typename _ForwardIterator>
+        static _ForwardIterator
+        uninitialized_copy(_InputIterator __first, _InputIterator __last,
+			   _ForwardIterator __result)
+        { return std::copy(__first, __last, __result); }
+    };
+
   /**
    *  @brief Copies the range [first,last) into result.
    *  @param  first  An input iterator.
@@ -98,34 +111,49 @@
     uninitialized_copy(_InputIterator __first, _InputIterator __last,
 		       _ForwardIterator __result)
     {
+      typedef typename iterator_traits<_InputIterator>::value_type
+	_ValueType1;
       typedef typename iterator_traits<_ForwardIterator>::value_type
-	_ValueType;
-      if (__is_pod(_ValueType))
-	return std::copy(__first, __last, __result);
-      else
-	return std::__uninitialized_copy_aux(__first, __last, __result);
+	_ValueType2;
+
+      return std::__uninitialized_copy<(__is_pod(_ValueType1)
+					&& __is_pod(_ValueType2))>::
+	uninitialized_copy(__first, __last, __result);
     }
 
 
-  template<typename _ForwardIterator, typename _Tp>
-    void
-    __uninitialized_fill_aux(_ForwardIterator __first,
-			     _ForwardIterator __last,
-			     const _Tp& __x)
+  template<bool>
+    struct __uninitialized_fill
     {
-      _ForwardIterator __cur = __first;
-      try
-	{
-	  for (; __cur != __last; ++__cur)
-	    std::_Construct(&*__cur, __x);
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        uninitialized_fill(_ForwardIterator __first,
+			   _ForwardIterator __last, const _Tp& __x)
+        {
+	  _ForwardIterator __cur = __first;
+	  try
+	    {
+	      for (; __cur != __last; ++__cur)
+		std::_Construct(&*__cur, __x);
+	    }
+	  catch(...)
+	    {
+	      std::_Destroy(__first, __cur);
+	      __throw_exception_again;
+	    }
 	}
-      catch(...)
-	{
-	  std::_Destroy(__first, __cur);
-	  __throw_exception_again;
-	}
-    }
+    };
 
+  template<>
+    struct __uninitialized_fill<true>
+    {
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        uninitialized_fill(_ForwardIterator __first,
+			   _ForwardIterator __last, const _Tp& __x)
+        { std::fill(__first, __last, __x); }
+    };
+
   /**
    *  @brief Copies the value x into the range [first,last).
    *  @param  first  An input iterator.
@@ -142,31 +170,44 @@
     {
       typedef typename iterator_traits<_ForwardIterator>::value_type
 	_ValueType;
-      if (__is_pod(_ValueType))
-	std::fill(__first, __last, __x);
-      else
-	std::__uninitialized_fill_aux(__first, __last, __x);
+
+      std::__uninitialized_fill<__is_pod(_ValueType)>::
+	uninitialized_fill(__first, __last, __x);
     }
 
 
-  template<typename _ForwardIterator, typename _Size, typename _Tp>
-    void
-    __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
-			       const _Tp& __x)
+  template<bool>
+    struct __uninitialized_fill_n
     {
-      _ForwardIterator __cur = __first;
-      try
-	{
-	  for (; __n > 0; --__n, ++__cur)
-	    std::_Construct(&*__cur, __x);
+      template<typename _ForwardIterator, typename _Size, typename _Tp>
+        static void
+        uninitialized_fill_n(_ForwardIterator __first, _Size __n,
+			     const _Tp& __x)
+        {
+	  _ForwardIterator __cur = __first;
+	  try
+	    {
+	      for (; __n > 0; --__n, ++__cur)
+		std::_Construct(&*__cur, __x);
+	    }
+	  catch(...)
+	    {
+	      std::_Destroy(__first, __cur);
+	      __throw_exception_again;
+	    }
 	}
-      catch(...)
-	{
-	  std::_Destroy(__first, __cur);
-	  __throw_exception_again;
-	}
-    }
+    };
 
+  template<>
+    struct __uninitialized_fill_n<true>
+    {
+      template<typename _ForwardIterator, typename _Size, typename _Tp>
+        static void
+        uninitialized_fill_n(_ForwardIterator __first, _Size __n,
+			     const _Tp& __x)
+        { std::fill_n(__first, __n, __x); }
+    };
+
   /**
    *  @brief Copies the value x into the range [first,first+n).
    *  @param  first  An input iterator.
@@ -182,10 +223,9 @@
     {
       typedef typename iterator_traits<_ForwardIterator>::value_type
 	_ValueType;
-      if (__is_pod(_ValueType))
-	std::fill_n(__first, __n, __x);
-      else
-	std::__uninitialized_fill_n_aux(__first, __n, __x);
+
+      std::__uninitialized_fill_n<__is_pod(_ValueType)>::
+	uninitialized_fill_n(__first, __n, __x);
     }
 
   // Extensions: versions of uninitialized_copy, uninitialized_fill,
Index: testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
===================================================================
--- testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(revision 125217)
+++ testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(working copy)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 845 }
+// { dg-error "no matching" "" { target *-*-* } 846 }
 // { dg-excess-errors "" }
 
 #include <vector>
Index: testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
===================================================================
--- testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(revision 125217)
+++ testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(working copy)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 886 }
+// { dg-error "no matching" "" { target *-*-* } 887 }
 // { dg-excess-errors "" }
 
 #include <vector>
Index: testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
===================================================================
--- testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(revision 125217)
+++ testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(working copy)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no match" "" { target *-*-* } 622 }
+// { dg-error "no matching" "" { target *-*-* } 787 }
 // { dg-excess-errors "" }
 
 #include <vector>
Index: testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
===================================================================
--- testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(revision 125217)
+++ testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(working copy)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no match" "" { target *-*-* } 622 }
+// { dg-error "no matching" "" { target *-*-* } 787 }
 // { dg-excess-errors "" }
 
 #include <vector>
Index: testsuite/20_util/specialized_algorithms/32158.cc
===================================================================
--- testsuite/20_util/specialized_algorithms/32158.cc	(revision 0)
+++ testsuite/20_util/specialized_algorithms/32158.cc	(revision 0)
@@ -0,0 +1,35 @@
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.4.4 specialized algorithms
+
+// { dg-do compile }
+
+#include <memory>
+#include <utility>
+
+// c++/32158
+
+typedef std::pair<const int, int> MyPair;
+
+void
+Alpha(MyPair* start, MyPair* end)
+{
+  MyPair my_pair(1, 2);
+  std::uninitialized_fill(start, end, my_pair);
+};

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