xref: /llvm-project/clang/test/SemaTemplate/GH18291.cpp (revision e0ad34e56590fa2e6ffdf617e044de7eadee2139)
1 // RUN: %clang_cc1 -std=c++23 -verify %s
2 
3 namespace t1 {
4   template<bool> struct enable_if { typedef void type; };
5   template <class T> class Foo {};
6   template <class X> constexpr bool check() { return true; }
7   template <class X, class Enable = void> struct Bar {};
8 
9   namespace param {
10     template<class X> void func(Bar<X, typename enable_if<check<X>()>::type>) {}
11     // expected-note@-1 2{{candidate function}}
12     template<class T> void func(Bar<Foo<T>>) {}
13     // expected-note@-1 2{{candidate function}}
14 
15     void g() {
16       func(Bar<Foo<int>>()); // expected-error {{call to 'func' is ambiguous}}
17       void (*ptr)(Bar<Foo<int>>){func};
18       // expected-error@-1 {{address of overloaded function 'func' is ambiguous}}
19     }
20   } // namespace param
21   namespace ret {
22     template<class X> Bar<X, typename enable_if<check<X>()>::type> func();
23     // expected-note@-1 {{candidate function}}
24     template<class T> Bar<Foo<T>> func();
25     // expected-note@-1 {{candidate function}}
26 
27     void g() {
28       Bar<Foo<int>> (*ptr)(){func};
29       // expected-error@-1 {{address of overloaded function 'func' is ambiguous}}
30     }
31   } // namespace ret
32   namespace conv {
33     struct A {
34       template<class X> operator Bar<X, typename enable_if<check<X>()>::type>();
35       // expected-note@-1 {{candidate function}}
36       template<class T> operator Bar<Foo<T>>();
37       // expected-note@-1 {{candidate function}}
38     };
39     void g() {
40       Bar<Foo<int>> x = A();
41       // expected-error@-1 {{conversion from 'A' to 'Bar<Foo<int>>' is ambiguous}}
42     }
43   } // namespace conv
44 } // namespace t1
45 
46 namespace t2 {
47   template <bool> struct enable_if;
48   template <> struct enable_if<true> {
49     typedef int type;
50   };
51   struct pair {
52     template <int = 0> pair(int);
53     template <class _U2, enable_if<__is_constructible(int &, _U2)>::type = 0>
54     pair(_U2 &&);
55   };
56   int test_test_i;
57   void test() { pair{test_test_i}; }
58 } // namespace t2
59 
60 namespace t3 {
61   template <class _Tp> void to_address(_Tp);
62   template <class _Pointer> auto to_address(_Pointer __p) -> decltype(__p);
63 
64   template <class _CharT> struct basic_string_view {
65     basic_string_view(_CharT);
66 
67     template <class _It> requires requires(_It __i) { to_address(__i); }
68     basic_string_view(_It);
69   };
70   void operatorsv() { basic_string_view(0); }
71 } // namespace t3
72 
73 namespace func_pointer {
74   template <class> struct __promote {
75     using type = float;
76   };
77   template <class> class complex {};
78 
79   namespace ret {
80     template <class _Tp> complex<_Tp> pow(const complex<_Tp> &) {};
81     template <class _Tp> complex<typename __promote<_Tp>::type> pow(_Tp) = delete;
82     complex<float> (*ptr)(const complex<float> &){pow};
83   } // namespace ret
84   namespace param {
85     template <class _Tp> void pow(const complex<_Tp> &, complex<_Tp>) {};
86     template <class _Tp> void pow(_Tp, complex<typename __promote<_Tp>::type>) = delete;
87     void (*ptr)(const complex<float> &, complex<float>){pow};
88   } // namespace param
89 } // namespace func_pointer
90 
91 namespace static_vs_nonstatic {
92   namespace implicit_obj_param {
93     struct A {
94       template <class... Args>
95         static void f(int a, Args... args) {}
96       template <class... Args>
97         void f(Args... args) = delete;
98     };
99     void g(){
100       A::f(0);
101     }
102   } // namespace implicit_obj_param
103   namespace explicit_obj_param {
104     struct A {
105       template <class... Args>
106         static void f(int, Args... args) {}
107       template <class... Args>
108         void f(this A *, Args... args) = delete;
109     };
110     void g(){
111       A::f(0);
112     }
113   } // namespace explicit_obj_param
114 } // namespace static_vs_nonstatic
115 
116 namespace incomplete_on_sugar {
117   template <unsigned P, class T> void f(T[P]) = delete;
118   template <unsigned P> void f(int[][P]);
119   void test() {
120     int array[1][8];
121     f<8>(array);
122   }
123 } // namespace incomplete_on_sugar
124