diff options
Diffstat (limited to 'test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp')
-rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp index bc074ba25e..f0ab7b8ea7 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p7.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++2a -verify %s struct Q { typedef int type; }; @@ -20,3 +21,36 @@ template<typename T, template<typename T::type...> class ...X> void c(T); int &c(...); int &c_disabled = c(0); int &c_enabled = c(Q()); // expected-error {{cannot bind to a temporary of type 'void'}} + +// The substitution proceeds in lexical order and stops when a condition that +// causes deduction to fail is encountered. +#if __cplusplus > 201702L +namespace reversed_operator_substitution_order { + struct X { X(int); }; + struct Y { Y(int); }; + struct Cat {}; + namespace no_adl { + Cat operator<=>(Y, X); + bool operator<(int, Cat); + + template<typename T> struct indirect_sizeof { + static_assert(sizeof(T) != 0); + static const auto value = sizeof(T); + }; + + // We should substitute into the construction of the X object before the + // construction of the Y object, so this is a SFINAE case rather than a + // hard error. This requires substitution to proceed in lexical order + // despite the prior rewrite to + // 0 < (Y(...) <=> X(...)) + template<typename T> float &f( + decltype( + X(sizeof(T)) < Y(indirect_sizeof<T>::value) + ) + ); + template<typename T> int &f(...); + } + int &r = no_adl::f<void>(true); + float &s = no_adl::f<int>(true); +} +#endif |