Work around http://gcc.gnu.org/PR52796 in gcc-4.6 by adding an overload of each function that passes a parameter pack directly as the only arguments of an object's constructor, which explicitly takes no arguments in place of the pack.
Tested with check-c++ and by trying to provoke the bug in valgrind for each changed location. Some of the insert_aux locations appear inaccessible because of missing emplace() functions. I plan to only apply this to the google/gcc-4_6 branch, since gcc-4.7 already makes these cases work properly. 2012-03-30 Jeffrey Yasskin <jyass...@google.com> * libstdc++-v3/include/ext/pool_allocator.h: Add 1-argument construct() method. * libstdc++-v3/include/ext/bitmap_allocator.h: Likewise. * libstdc++-v3/include/ext/new_allocator.h: Likewise. * libstdc++-v3/include/ext/malloc_allocator.h: Likewise. * libstdc++-v3/include/ext/array_allocator.h: Likewise. * libstdc++-v3/include/ext/mt_allocator.h: Likewise. * libstdc++-v3/include/ext/extptr_allocator.h: Likewise. * libstdc++-v3/include/bits/stl_construct.h:Add 1-argument _Construct function. * libstdc++-v3/include/bits/stl_list.h: Add default _List_node constructor. * libstdc++-v3/include/bits/hashtable_policy.h: Add default _Hash_node constructor. * libstdc++-v3/include/bits/forward_list.h:Add default _Fwd_list_node constructor. * libstdc++-v3/include/bits/stl_tree.h:Add default _Rb_tree_node constructor. * libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc: Update line numbers. * libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc: Likewise. * libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc: Likewise. Index: libstdc++-v3/include/ext/pool_allocator.h =================================================================== --- libstdc++-v3/include/ext/pool_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/pool_allocator.h (working copy) @@ -165,6 +165,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) _Tp(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/ext/bitmap_allocator.h =================================================================== --- libstdc++-v3/include/ext/bitmap_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/bitmap_allocator.h (working copy) @@ -1058,6 +1058,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) value_type(__data); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) @@ -1109,4 +1115,3 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif - Index: libstdc++-v3/include/ext/new_allocator.h =================================================================== --- libstdc++-v3/include/ext/new_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/new_allocator.h (working copy) @@ -115,6 +115,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) _Tp(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/ext/malloc_allocator.h =================================================================== --- libstdc++-v3/include/ext/malloc_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/malloc_allocator.h (working copy) @@ -111,6 +111,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) value_type(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/ext/array_allocator.h =================================================================== --- libstdc++-v3/include/ext/array_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/array_allocator.h (working copy) @@ -79,6 +79,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) value_type(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/ext/mt_allocator.h =================================================================== --- libstdc++-v3/include/ext/mt_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/mt_allocator.h (working copy) @@ -595,6 +595,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new((void *)__p) _Tp(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new((void *)__p) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/ext/extptr_allocator.h =================================================================== --- libstdc++-v3/include/ext/extptr_allocator.h (revision 186024) +++ libstdc++-v3/include/ext/extptr_allocator.h (working copy) @@ -104,6 +104,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ::new(__p.get()) _Tp(__val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + void + construct(pointer __p) + { ::new(__p.get()) _Tp(); } + template<typename... _Args> void construct(pointer __p, _Args&&... __args) Index: libstdc++-v3/include/bits/stl_list.h =================================================================== --- libstdc++-v3/include/bits/stl_list.h (revision 186024) +++ libstdc++-v3/include/bits/stl_list.h (working copy) @@ -108,6 +108,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Tp _M_data; #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + _List_node() + : __detail::_List_node_base(), _M_data() + { } + template<typename... _Args> _List_node(_Args&&... __args) : __detail::_List_node_base(), _M_data(std::forward<_Args>(__args)...) Index: libstdc++-v3/include/bits/hashtable_policy.h =================================================================== --- libstdc++-v3/include/bits/hashtable_policy.h (revision 186024) +++ libstdc++-v3/include/bits/hashtable_policy.h (working copy) @@ -76,6 +76,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::size_t _M_hash_code; _Hash_node* _M_next; + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + _Hash_node() + : _M_v(), + _M_hash_code(), _M_next() { } + template<typename... _Args> _Hash_node(_Args&&... __args) : _M_v(std::forward<_Args>(__args)...), @@ -88,6 +94,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Value _M_v; _Hash_node* _M_next; + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + _Hash_node() + : _M_v(), + _M_next() { } + template<typename... _Args> _Hash_node(_Args&&... __args) : _M_v(std::forward<_Args>(__args)...), Index: libstdc++-v3/include/bits/forward_list.h =================================================================== --- libstdc++-v3/include/bits/forward_list.h (revision 186024) +++ libstdc++-v3/include/bits/forward_list.h (working copy) @@ -100,6 +100,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER struct _Fwd_list_node : public _Fwd_list_node_base { + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + _Fwd_list_node() + : _Fwd_list_node_base(), + _M_value() { } + template<typename... _Args> _Fwd_list_node(_Args&&... __args) : _Fwd_list_node_base(), Index: libstdc++-v3/include/bits/stl_construct.h =================================================================== --- libstdc++-v3/include/bits/stl_construct.h (revision 186024) +++ libstdc++-v3/include/bits/stl_construct.h (working copy) @@ -70,6 +70,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * object's constructor with an initializer. */ #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + template<typename _T1> + inline void + _Construct(_T1* __p) + { ::new(static_cast<void*>(__p)) _T1(); } + template<typename _T1, typename... _Args> inline void _Construct(_T1* __p, _Args&&... __args) @@ -157,4 +164,3 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_CONSTRUCT_H */ - Index: libstdc++-v3/include/bits/stl_tree.h =================================================================== --- libstdc++-v3/include/bits/stl_tree.h (revision 186024) +++ libstdc++-v3/include/bits/stl_tree.h (working copy) @@ -133,6 +133,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Val _M_value_field; #ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Work around PR52796 by avoiding 0-length parameter packs + // passed to constructors. + _Rb_tree_node() + : _Rb_tree_node_base(), + _M_value_field() { } + template<typename... _Args> _Rb_tree_node(_Args&&... __args) : _Rb_tree_node_base(), Index: libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1206 } +// { dg-error "no matching" "" { target *-*-* } 1212 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010 Free Software Foundation Index: libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1206 } +// { dg-error "no matching" "" { target *-*-* } 1212 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010, 2011 Free Software Foundation Index: libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1206 } +// { dg-error "no matching" "" { target *-*-* } 1212 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010, 2011 Free Software Foundation Index: libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1206 } +// { dg-error "no matching" "" { target *-*-* } 1212 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010, 2011 Free Software Foundation Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1491 } +// { dg-error "no matching" "" { target *-*-* } 1497 } // { dg-excess-errors "" } #include <list> Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1447 } +// { dg-error "no matching" "" { target *-*-* } 1453 } // { dg-excess-errors "" } #include <list> Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1447 } +// { dg-error "no matching" "" { target *-*-* } 1453 } // { dg-excess-errors "" } #include <list> Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc (revision 186024) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1447 } +// { dg-error "no matching" "" { target *-*-* } 1453 } // { dg-excess-errors "" } #include <list> -- This patch is available for review at http://codereview.appspot.com/5971053