Author: ericwf Date: Thu Sep 14 17:31:38 2017 New Revision: 313324 URL: http://llvm.org/viewvc/llvm-project?rev=313324&view=rev Log: Fix accidental ADL in std::allocator_traits meta-programming.
There were a number of cases where __double_underscore functions, for example __has_construct_test, were called without being qualified, causing ADL to occur. This patch qualifies those calls to avoid this problem. Thanks to David L. Jones for point out the issue initially. Added: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/incomplete_type_helper.h Modified: libcxx/trunk/include/memory libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Thu Sep 14 17:31:38 2017 @@ -1302,7 +1302,7 @@ struct __allocator_traits_rebind<_Alloc< template <class _Alloc, class _SizeType, class _ConstVoidPtr> auto __has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p) - -> decltype(__a.allocate(__sz, __p), true_type()); + -> decltype((void)__a.allocate(__sz, __p), true_type()); template <class _Alloc, class _SizeType, class _ConstVoidPtr> auto @@ -1313,7 +1313,7 @@ template <class _Alloc, class _SizeType, struct __has_allocate_hint : integral_constant<bool, is_same< - decltype(__has_allocate_hint_test(declval<_Alloc>(), + decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(), declval<_SizeType>(), declval<_ConstVoidPtr>())), true_type>::value> @@ -1346,7 +1346,7 @@ template <class _Alloc, class _Pointer, struct __has_construct : integral_constant<bool, is_same< - decltype(__has_construct_test(declval<_Alloc>(), + decltype(_VSTD::__has_construct_test(declval<_Alloc>(), declval<_Pointer>(), declval<_Args>()...)), true_type>::value> @@ -1367,7 +1367,7 @@ template <class _Alloc, class _Pointer> struct __has_destroy : integral_constant<bool, is_same< - decltype(__has_destroy_test(declval<_Alloc>(), + decltype(_VSTD::__has_destroy_test(declval<_Alloc>(), declval<_Pointer>())), true_type>::value> { @@ -1387,7 +1387,7 @@ template <class _Alloc> struct __has_max_size : integral_constant<bool, is_same< - decltype(__has_max_size_test(declval<_Alloc&>())), + decltype(_VSTD::__has_max_size_test(declval<_Alloc&>())), true_type>::value> { }; @@ -1406,7 +1406,7 @@ template <class _Alloc> struct __has_select_on_container_copy_construction : integral_constant<bool, is_same< - decltype(__has_select_on_container_copy_construction_test(declval<_Alloc&>())), + decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>())), true_type>::value> { }; Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp Thu Sep 14 17:31:38 2017 @@ -20,6 +20,8 @@ #include <cstdint> #include <cassert> +#include "incomplete_type_helper.h" + template <class T> struct A { @@ -34,6 +36,14 @@ struct A int main() { + { A<int> a; assert(std::allocator_traits<A<int> >::allocate(a, 10) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF))); + } + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + assert(std::allocator_traits<Alloc >::allocate(a, 10) == reinterpret_cast<VT*>(static_cast<std::uintptr_t>(0xDEADBEEF))); + } } Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp Thu Sep 14 17:31:38 2017 @@ -21,6 +21,7 @@ #include <cassert> #include "test_macros.h" +#include "incomplete_type_helper.h" template <class T> struct A @@ -52,12 +53,29 @@ struct B } }; + int main() { #if TEST_STD_VER >= 11 + { A<int> a; assert(std::allocator_traits<A<int> >::allocate(a, 10, nullptr) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF))); + } + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + assert(std::allocator_traits<Alloc >::allocate(a, 10, nullptr) == reinterpret_cast<VT*>(static_cast<std::uintptr_t>(0xDEADBEEF))); + } #endif + { B<int> b; assert(std::allocator_traits<B<int> >::allocate(b, 11, nullptr) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xFEADBEEF))); + } + { + typedef IncompleteHolder* VT; + typedef B<VT> Alloc; + Alloc b; + assert(std::allocator_traits<Alloc >::allocate(b, 11, nullptr) == reinterpret_cast<VT*>(static_cast<std::uintptr_t>(0xFEADBEEF))); + } } Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp Thu Sep 14 17:31:38 2017 @@ -23,6 +23,7 @@ #include <cassert> #include "test_macros.h" +#include "incomplete_type_helper.h" template <class T> struct A @@ -107,6 +108,13 @@ int main() std::allocator_traits<A<int> >::construct(a, (A2*)&a2, 'd', 5); assert(A2::count == 1); } + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + std::aligned_storage<sizeof(VT)>::type store; + std::allocator_traits<Alloc>::construct(a, (VT*)&store, nullptr); + } #if TEST_STD_VER >= 11 { A0::count = 0; Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp Thu Sep 14 17:31:38 2017 @@ -20,6 +20,8 @@ #include <cstdint> #include <cassert> +#include "incomplete_type_helper.h" + int called = 0; template <class T> @@ -37,7 +39,17 @@ struct A int main() { + { A<int> a; std::allocator_traits<A<int> >::deallocate(a, reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF)), 10); assert(called == 1); + } + called = 0; + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + std::allocator_traits<Alloc >::deallocate(a, reinterpret_cast<VT*>(static_cast<std::uintptr_t>(0xDEADBEEF)), 10); + assert(called == 1); + } } Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp Thu Sep 14 17:31:38 2017 @@ -23,6 +23,7 @@ #include <cassert> #include "test_macros.h" +#include "incomplete_type_helper.h" template <class T> struct A @@ -65,6 +66,13 @@ int main() std::allocator_traits<A<int> >::destroy(a, (A0*)&a0); assert(A0::count == 1); } + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + std::aligned_storage<sizeof(VT)>::type store; + std::allocator_traits<Alloc>::destroy(a, (VT*)&store); + } #if TEST_STD_VER >= 11 { A0::count = 0; Added: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/incomplete_type_helper.h URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/incomplete_type_helper.h?rev=313324&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/incomplete_type_helper.h (added) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/incomplete_type_helper.h Thu Sep 14 17:31:38 2017 @@ -0,0 +1,14 @@ +#ifndef TEST_INCOMPLETE_TYPE_HELPER_H +#define TEST_INCOMPLETE_TYPE_HELPER_H + +#include "min_allocator.h" + +namespace NS { + struct Incomplete; +} + +template <class T> struct Holder { T value; }; + +typedef Holder<NS::Incomplete> IncompleteHolder; + +#endif Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp Thu Sep 14 17:31:38 2017 @@ -22,6 +22,7 @@ #include <cassert> #include "test_macros.h" +#include "incomplete_type_helper.h" template <class T> struct A @@ -51,6 +52,12 @@ int main() const B<int> b = {}; assert(std::allocator_traits<B<int> >::max_size(b) == 100); } + { + typedef IncompleteHolder* VT; + typedef B<VT> Alloc; + Alloc a; + assert(std::allocator_traits<Alloc >::max_size(a) == 100); + } #if TEST_STD_VER >= 11 { A<int> a; Modified: libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp?rev=313324&r1=313323&r2=313324&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp Thu Sep 14 17:31:38 2017 @@ -23,6 +23,7 @@ #include <cassert> #include "test_macros.h" +#include "incomplete_type_helper.h" template <class T> struct A @@ -57,6 +58,12 @@ int main() const A<int> a(0); assert(std::allocator_traits<A<int> >::select_on_container_copy_construction(a).id == 0); } + { + typedef IncompleteHolder* VT; + typedef A<VT> Alloc; + Alloc a; + assert(std::allocator_traits<Alloc>::select_on_container_copy_construction(a).id == 0); + } #if TEST_STD_VER >= 11 { B<int> b; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits