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]

[patch] Make std::list safe against overloaded operator&


This fixes some unsafe uses of operator& in std::list, and also in
Debug Mode found running the new test with -D_GLIBCXX_DEBUG.

Tested powerpc64le-linux, committed to trunk.

commit 588d91ac5190efb29369da9bec60d069fd7891cd
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jun 16 19:12:08 2015 +0100

    	* include/bits/list.tcc (list::operator=(const list&), list::merge):
    	Use __addressof instead of operator&.
    	(list::sort): Use array-to-pointer decay instead of operator&.
    	* include/bits/stl_list.h (list::splice): Use __addressof instead of
    	operator&.
    	* include/debug/formatter.h (_Error_formatter::_Parameter::_Parameter):
    	Likewise.
    	* include/debug/functions.h (__check_singular): Likewise.
    	* include/debug/list (list::splice, list::merge): Likewise.
    	* testsuite/23_containers/list/modifiers/addressof.cc: New.

diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index c5d2ab4..95193c1 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -265,7 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     list<_Tp, _Alloc>::
     operator=(const list& __x)
     {
-      if (this != &__x)
+      if (this != std::__addressof(__x))
 	{
 	  iterator __first1 = begin();
 	  iterator __last1 = end();
@@ -373,7 +373,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 300. list::merge() specification incomplete
-      if (this != &__x)
+      if (this != std::__addressof(__x))
 	{
 	  _M_check_equal_allocators(__x); 
 
@@ -410,7 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 300. list::merge() specification incomplete
-	if (this != &__x)
+	if (this != std::__addressof(__x))
 	  {
 	    _M_check_equal_allocators(__x);
 
@@ -446,14 +446,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
         list __carry;
         list __tmp[64];
-        list * __fill = &__tmp[0];
+        list * __fill = __tmp;
         list * __counter;
 
         do
 	  {
 	    __carry.splice(__carry.begin(), *this, begin());
 
-	    for(__counter = &__tmp[0];
+	    for(__counter = __tmp;
 		__counter != __fill && !__counter->empty();
 		++__counter)
 	      {
@@ -466,7 +466,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  }
 	while ( !empty() );
 
-        for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
+        for (__counter = __tmp + 1; __counter != __fill; ++__counter)
           __counter->merge(*(__counter - 1));
         swap( *(__fill - 1) );
       }
@@ -523,14 +523,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  {
 	    list __carry;
 	    list __tmp[64];
-	    list * __fill = &__tmp[0];
+	    list * __fill = __tmp;
 	    list * __counter;
 
 	    do
 	      {
 		__carry.splice(__carry.begin(), *this, begin());
 
-		for(__counter = &__tmp[0];
+		for(__counter = __tmp;
 		    __counter != __fill && !__counter->empty();
 		    ++__counter)
 		  {
@@ -543,7 +543,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	      }
 	    while ( !empty() );
 
-	    for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
+	    for (__counter = __tmp + 1; __counter != __fill; ++__counter)
 	      __counter->merge(*(__counter - 1), __comp);
 	    swap(*(__fill - 1));
 	  }
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index a26859e..a498de5 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1438,7 +1438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 	if (__position == __i || __position == __j)
 	  return;
 
-	if (this != &__x)
+	if (this != std::__addressof(__x))
 	  _M_check_equal_allocators(__x);
 
 	this->_M_transfer(__position._M_const_cast(),
@@ -1501,7 +1501,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       {
 	if (__first != __last)
 	  {
-	    if (this != &__x)
+	    if (this != std::__addressof(__x))
 	      _M_check_equal_allocators(__x);
 
 	    size_t __n = this->_M_distance(__first._M_node, __last._M_node);
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 3786839..56ee807 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -241,7 +241,7 @@ namespace __gnu_debug
 	: _M_kind(__iterator),  _M_variant()
 	{
 	  _M_variant._M_iterator._M_name = __name;
-	  _M_variant._M_iterator._M_address = &__it;
+	  _M_variant._M_iterator._M_address = std::__addressof(__it);
 	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness =
 	    std::__are_same<_Safe_iterator<_Iterator, _Sequence>,
@@ -271,7 +271,7 @@ namespace __gnu_debug
 	: _M_kind(__iterator),  _M_variant()
 	{
 	  _M_variant._M_iterator._M_name = __name;
-	  _M_variant._M_iterator._M_address = &__it;
+	  _M_variant._M_iterator._M_address = std::__addressof(__it);
 	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness =
 	    std::__are_same<_Safe_local_iterator<_Iterator, _Sequence>,
@@ -298,7 +298,7 @@ namespace __gnu_debug
 	: _M_kind(__iterator), _M_variant()
 	{
 	  _M_variant._M_iterator._M_name = __name;
-	  _M_variant._M_iterator._M_address = &__it;
+	  _M_variant._M_iterator._M_address = std::__addressof(__it);
 	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __const_iterator;
 	  _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
@@ -311,7 +311,7 @@ namespace __gnu_debug
 	: _M_kind(__iterator), _M_variant()
 	{
 	  _M_variant._M_iterator._M_name = __name;
-	  _M_variant._M_iterator._M_address = &__it;
+	  _M_variant._M_iterator._M_address = std::__addressof(__it);
 	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __mutable_iterator;
 	  _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
@@ -324,7 +324,7 @@ namespace __gnu_debug
 	: _M_kind(__iterator), _M_variant()
 	{
 	  _M_variant._M_iterator._M_name = __name;
-	  _M_variant._M_iterator._M_address = &__it;
+	  _M_variant._M_iterator._M_address = std::__addressof(__it);
 	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __unknown_constness;
 	  _M_variant._M_iterator._M_state =
@@ -340,7 +340,7 @@ namespace __gnu_debug
 	{
 	  _M_variant._M_sequence._M_name = __name;
 	  _M_variant._M_sequence._M_address =
-	    static_cast<const _Sequence*>(&__seq);
+	    static_cast<const _Sequence*>(std::__addressof(__seq));
 	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
 	}
 
@@ -349,7 +349,7 @@ namespace __gnu_debug
 	: _M_kind(__sequence), _M_variant()
 	{
 	  _M_variant._M_sequence._M_name = __name;
-	  _M_variant._M_sequence._M_address = &__seq;
+	  _M_variant._M_sequence._M_address = std::__addressof(__seq);
 	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
 	}
 
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 4a245dd..bf60ccc 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -64,7 +64,7 @@ namespace __gnu_debug
   template<typename _Iterator>
     inline bool
     __check_singular(const _Iterator& __x)
-    { return __check_singular_aux(&__x); }
+    { return __check_singular_aux(std::__addressof(__x)); }
 
   /** Non-NULL pointers are nonsingular. */
   template<typename _Tp>
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 41ed7f5..9f4c9c0 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -524,7 +524,7 @@ namespace __debug
       splice(iterator __position, list& __x)
 #endif
       {
-	_GLIBCXX_DEBUG_VERIFY(&__x != this,
+	_GLIBCXX_DEBUG_VERIFY(std::__addressof(__x) != this,
 			      _M_message(__gnu_debug::__msg_self_splice)
 			      ._M_sequence(*this, "this"));
 	this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
@@ -552,7 +552,7 @@ namespace __debug
 	_GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
 			      _M_message(__gnu_debug::__msg_splice_bad)
 			      ._M_iterator(__i, "__i"));
-	_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
+	_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(std::__addressof(__x)),
 			      _M_message(__gnu_debug::__msg_splice_other)
 			     ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
 
@@ -580,7 +580,7 @@ namespace __debug
       {
 	__glibcxx_check_insert(__position);
 	__glibcxx_check_valid_range(__first, __last);
-	_GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
+	_GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(std::__addressof(__x)),
 			      _M_message(__gnu_debug::__msg_splice_other)
 			      ._M_sequence(__x, "x")
 			      ._M_iterator(__first, "first"));
@@ -595,7 +595,8 @@ namespace __debug
 				  _M_message(__gnu_debug::__msg_valid_range)
 				  ._M_iterator(__first, "first")
 				  ._M_iterator(__last, "last"));
-	    _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position.base(),
+	    _GLIBCXX_DEBUG_VERIFY(std::__addressof(__x) != this
+				  || __tmp != __position.base(),
 				_M_message(__gnu_debug::__msg_splice_overlap)
 				  ._M_iterator(__tmp, "position")
 				  ._M_iterator(__first, "first")
@@ -685,7 +686,7 @@ namespace __debug
       {
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 300. list::merge() specification incomplete
-	if (this != &__x)
+	if (this != std::__addressof(__x))
 	  {
 	    __glibcxx_check_sorted(_Base::begin(), _Base::end());
 	    __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
@@ -710,7 +711,7 @@ namespace __debug
 	{
 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	  // 300. list::merge() specification incomplete
-	  if (this != &__x)
+	  if (this != std::__addressof(__x))
 	    {
 	      __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
 					  __comp);
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/addressof.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/addressof.cc
new file mode 100644
index 0000000..b4429dd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/addressof.cc
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <list>
+
+namespace N
+{
+  // This operator& must not be found by ADL.
+  template<typename T> void operator&(const T&) { }
+  struct X { };
+  bool operator==(const X&, const X&);
+  bool operator<(const X&, const X&);
+}
+
+template class std::list<N::X>;

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