blob: b8f5a82d461bfa12dcee4fc402e319a464a99b8a [file] [log] [blame]
Richard Smith600b5262017-01-26 20:40:47 +00001// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
2
Richard Smith60437622017-02-09 19:17:44 +00003template <typename T> struct A { // expected-note 35{{declared here}}
4 constexpr A() {}
5 constexpr A(int) {}
6 constexpr operator int() { return 0; }
7};
8A() -> A<int>;
9A(int) -> A<int>;
Richard Smith600b5262017-01-26 20:40:47 +000010
11// Make sure we still correctly parse cases where a template can appear without arguments.
12namespace template_template_arg {
13 template<template<typename> typename> struct X {};
14 template<typename> struct Y {};
15
16 X<A> xa;
17 Y<A> ya; // expected-error {{requires template arguments}}
18 X<::A> xcca;
19 Y<::A> ycca; // expected-error {{requires template arguments}}
20
21 template<template<typename> typename = A> struct XD {};
22 template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
23 template<template<typename> typename = ::A> struct XCCD {};
24 template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
25
26 // FIXME: replacing the invalid type with 'int' here is horrible
Richard Smith60437622017-02-09 19:17:44 +000027 template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}}
Richard Smith600b5262017-01-26 20:40:47 +000028 template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
29}
30
31namespace injected_class_name {
32 template<typename T> struct A {
33 A(T);
Richard Smith32918772017-02-14 00:25:28 +000034 void f(int) { // expected-note {{previous}}
Richard Smith600b5262017-01-26 20:40:47 +000035 A a = 1;
Richard Smith32918772017-02-14 00:25:28 +000036 injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
Richard Smith600b5262017-01-26 20:40:47 +000037 }
NAKAMURA Takumieb7702e2017-02-14 03:18:24 +000038 void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}}
Richard Smith600b5262017-01-26 20:40:47 +000039 };
40 A<short> ai = 1;
41 A<double>::A b(1); // expected-error {{constructor name}}
42}
43
44struct member {
45 A a; // expected-error {{requires template arguments}}
46 A *b; // expected-error {{requires template arguments}}
47 const A c; // expected-error {{requires template arguments}}
48
49 void f() throw (A); // expected-error {{requires template arguments}}
50
51 friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
52
53 operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
54
Richard Smithd69f4f52017-02-10 21:40:29 +000055 static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
Richard Smith60437622017-02-09 19:17:44 +000056 static constexpr A y = 0;
Richard Smith600b5262017-01-26 20:40:47 +000057};
58
59namespace in_typedef {
60 typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
61 typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
62 typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
63}
64
65namespace stmt {
66 void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
67 try { }
68 catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
69 catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
70 try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
71
72 // FIXME: The standard only permits class template argument deduction in a
73 // simple-declaration or cast. We also permit it in conditions,
74 // for-range-declarations, member-declarations for static data members, and
75 // new-expressions, because not doing so would be bizarre.
Richard Smith60437622017-02-09 19:17:44 +000076 A local = 0;
77 static A local_static = 0;
78 static thread_local A thread_local_static = 0;
79 if (A a = 0) {}
80 if (A a = 0; a) {}
81 switch (A a = 0) {} // expected-warning {{no case matching constant switch condition '0'}}
82 switch (A a = 0; a) {} // expected-warning {{no case matching constant switch condition '0'}}
83 for (A a = 0; a; /**/) {}
84 for (/**/; A a = 0; /**/) {}
85 while (A a = 0) {}
Richard Smith600b5262017-01-26 20:40:47 +000086 int arr[3];
Richard Smith60437622017-02-09 19:17:44 +000087 for (A a : arr) {}
Richard Smith600b5262017-01-26 20:40:47 +000088 }
89
90 namespace std {
91 class type_info;
92 }
93}
94
95namespace expr {
96 template<typename T> struct U {};
97 void j() {
98 (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
99 (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
100 (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
101
102 U<A> v; // expected-error {{requires template arguments}}
103
104 int n;
105 (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
106 (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
107 (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
108 (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
109 (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
Richard Smithee579842017-01-30 20:39:26 +0000110 (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
111 (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
Richard Smith600b5262017-01-26 20:40:47 +0000112
Richard Smith60437622017-02-09 19:17:44 +0000113 (void)A(n);
114 (void)A{n};
115 (void)new A(n);
116 (void)new A{n};
Richard Smith600b5262017-01-26 20:40:47 +0000117 // FIXME: We should diagnose the lack of an initializer here.
Richard Smith60437622017-02-09 19:17:44 +0000118 (void)new A;
Richard Smith600b5262017-01-26 20:40:47 +0000119 }
120}
121
122namespace decl {
123 enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
124 struct F : A {}; // expected-error{{expected class name}}
125
126 using B = A; // expected-error{{requires template arguments}}
127
128 auto k() -> A; // expected-error{{requires template arguments}}
129
Richard Smithd69f4f52017-02-10 21:40:29 +0000130 A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
Richard Smith60437622017-02-09 19:17:44 +0000131 A b = 0;
132 const A c = 0;
Richard Smith600b5262017-01-26 20:40:47 +0000133 A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
134 A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
135 A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
136 A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
137 A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
138 A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
Richard Smith60437622017-02-09 19:17:44 +0000139 A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A<int>' decomposes into 0 elements, but 2 names were provided}}
Richard Smith600b5262017-01-26 20:40:47 +0000140}
Richard Smithee579842017-01-30 20:39:26 +0000141
142namespace typename_specifier {
143 struct F {};
144
145 void e() {
Richard Smith60437622017-02-09 19:17:44 +0000146 (void) typename ::A(0);
147 (void) typename ::A{0};
148 new typename ::A(0);
149 new typename ::A{0};
150 typename ::A a = 0;
151 const typename ::A b = 0;
152 if (typename ::A a = 0) {}
153 for (typename ::A a = 0; typename ::A b = 0; /**/) {}
Richard Smithee579842017-01-30 20:39:26 +0000154
155 (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
156 (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
157 }
Richard Smith60437622017-02-09 19:17:44 +0000158 typename ::A a = 0;
159 const typename ::A b = 0;
Richard Smithee579842017-01-30 20:39:26 +0000160 typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
161 typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
162 typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
163 typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
164 typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
165 typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
Richard Smith60437622017-02-09 19:17:44 +0000166 typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
Richard Smithee579842017-01-30 20:39:26 +0000167
Richard Smith32918772017-02-14 00:25:28 +0000168 struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}
Richard Smithee579842017-01-30 20:39:26 +0000169
170 template<typename T> void f() {
Richard Smith32918772017-02-14 00:25:28 +0000171 (void) typename T::A(0);
172 (void) typename T::A{0};
173 new typename T::A(0);
174 new typename T::A{0};
175 typename T::A a = 0;
176 const typename T::A b = 0;
177 if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
178 for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
Richard Smithee579842017-01-30 20:39:26 +0000179
180 {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
181 {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
182 {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
Richard Smithac63d632017-09-29 23:57:25 +0000183 // expected-warning@-1 {{disambiguated as redundant parentheses around declaration of variable named 'parens'}} expected-note@-1 {{add a variable name}} expected-note@-1{{remove parentheses}} expected-note@-1 {{add enclosing parentheses}}
Richard Smithee579842017-01-30 20:39:26 +0000184 {typename T::A *p = 0;} // expected-error {{refers to class template member}}
185 {typename T::A &r = *p;} // expected-error {{refers to class template member}}
186 {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
187 {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
188 {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
Richard Smith32918772017-02-14 00:25:28 +0000189 {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
Richard Smithee579842017-01-30 20:39:26 +0000190 }
191 template void f<X>(); // expected-note {{instantiation of}}
192
193 template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
194 void h() { g<X>(); } // expected-error {{no matching function}}
195}