Delete unused PoisonChecking utility pass
[llvm-project.git] / clang / test / CXX / temp / temp.fct.spec / temp.deduct / p7.cpp
blobf0ab7b8ea7612fa3fd0ef5ff70db532bfe251541
1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 // RUN: %clang_cc1 -std=c++2a -verify %s
4 struct Q { typedef int type; };
6 // "The substitution occurs in all types and expressions that are used in [...]
7 // template parameter declarations." In particular, we must substitute into the
8 // type of a parameter pack that is not a pack expansion, even if we know the
9 // corresponding argument pack is empty.
10 template<typename T, typename T::type...> void a(T);
11 int &a(...);
12 int &a_disabled = a(0);
13 int &a_enabled = a(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
15 template<typename T, template<typename T::type> class ...X> void b(T);
16 int &b(...);
17 int &b_disabled = b(0);
18 int &b_enabled = b(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
20 template<typename T, template<typename T::type...> class ...X> void c(T);
21 int &c(...);
22 int &c_disabled = c(0);
23 int &c_enabled = c(Q()); // expected-error {{cannot bind to a temporary of type 'void'}}
25 // The substitution proceeds in lexical order and stops when a condition that
26 // causes deduction to fail is encountered.
27 #if __cplusplus > 201702L
28 namespace reversed_operator_substitution_order {
29 struct X { X(int); };
30 struct Y { Y(int); };
31 struct Cat {};
32 namespace no_adl {
33 Cat operator<=>(Y, X);
34 bool operator<(int, Cat);
36 template<typename T> struct indirect_sizeof {
37 static_assert(sizeof(T) != 0);
38 static const auto value = sizeof(T);
41 // We should substitute into the construction of the X object before the
42 // construction of the Y object, so this is a SFINAE case rather than a
43 // hard error. This requires substitution to proceed in lexical order
44 // despite the prior rewrite to
45 // 0 < (Y(...) <=> X(...))
46 template<typename T> float &f(
47 decltype(
48 X(sizeof(T)) < Y(indirect_sizeof<T>::value)
51 template<typename T> int &f(...);
53 int &r = no_adl::f<void>(true);
54 float &s = no_adl::f<int>(true);
56 #endif