1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s 2 3 template <typename T> struct A { // expected-note 35{{declared here}} 4 constexpr A() {} 5 constexpr A(int) {} 6 constexpr operator int() { return 0; } 7 }; 8 A() -> A<int>; 9 A(int) -> A<int>; 10 11 // Make sure we still correctly parse cases where a template can appear without arguments. 12 namespace 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 27 template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}} 28 template<typename T = A> struct G { }; // expected-error {{requires template arguments}} 29 } 30 31 namespace injected_class_name { 32 template<typename T> struct A { 33 A(T); 34 void f(int) { // expected-note {{previous}} 35 A a = 1; 36 injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}} 37 } 38 void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}} 39 }; 40 A<short> ai = 1; 41 A<double>::A b(1); // expected-error {{constructor name}} 42 } 43 44 struct 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 55 static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}} 56 static constexpr A y = 0; 57 }; 58 59 namespace 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 65 namespace 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. 76 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) {} 86 int arr[3]; 87 for (A a : arr) {} 88 } 89 90 namespace std { 91 class type_info; 92 } 93 } 94 95 namespace 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}} 110 (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}} 112 113 (void)A(n); 114 (void)A{n}; 115 (void)new A(n); 116 (void)new A{n}; 117 // FIXME: We should diagnose the lack of an initializer here. 118 (void)new A; 119 } 120 } 121 122 namespace 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 130 A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}} 131 A b = 0; 132 const A c = 0; 133 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}} 139 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}} 140 } 141 142 namespace typename_specifier { 143 struct F {}; 144 145 void e() { 146 (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; /**/) {} 154 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 } 158 typename ::A a = 0; 159 const typename ::A b = 0; 160 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}} 166 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}} 167 168 struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}} 169 170 template<typename T> void f() { 171 (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'}} 179 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}} 183 // 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}} 184 {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}} 189 {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}} 190 } 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 } 196