1 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
7 namespace dr705
{ // dr705: yes
10 void f(S
); // expected-note {{declared here}}
16 (f
)(s
); // expected-error {{use of undeclared}}
20 namespace dr712
{ // dr712: partial
23 const int a
= 0; // expected-note 5{{here}}
29 use((cond
, a
)); // expected-warning 2{{left operand of comma operator has no effect}} FIXME: should only warn once
31 (void)a
; // FIXME: expected-error {{declared in enclosing}}
32 (void)(a
); // FIXME: expected-error {{declared in enclosing}}
33 (void)(cond
? a
: a
); // FIXME: expected-error 2{{declared in enclosing}}
34 (void)(cond
, a
); // FIXME: expected-error {{declared in enclosing}} expected-warning {{left operand of comma operator has no effect}}
39 #if __cplusplus >= 201103L
42 constexpr A a
= {0}; // expected-note 2{{here}}
48 (void)a
.n
; // FIXME: expected-error {{declared in enclosing}}
49 (void)(a
.*&A::n
); // FIXME: expected-error {{declared in enclosing}}
56 namespace dr727
{ // dr727: partial
58 template<typename T
> struct C
; // expected-note 6{{here}}
59 template<typename T
> void f(); // expected-note {{here}}
60 template<typename T
> static int N
; // expected-error 0-1{{C++14}} expected-note 6{{here}}
62 template<> struct C
<int>;
63 template<> void f
<int>();
64 template<> static int N
<int>;
66 template<typename T
> struct C
<T
*>;
67 template<typename T
> static int N
<T
*>;
70 template<> struct C
<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
71 template<> void f
<float>(); // expected-error {{no function template matches}}
72 template<> static int N
<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
74 template<typename T
> struct C
<T
**>; // expected-error {{not in class 'A' or an enclosing namespace}}
75 template<typename T
> static int N
<T
**>; // expected-error {{not in class 'A' or an enclosing namespace}}
77 template<> struct A::C
<double>; // expected-error {{not in class 'A' or an enclosing namespace}}
78 template<> void A::f
<double>(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}}
79 template<> static int A::N
<double>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
81 template<typename T
> struct A::C
<T
***>; // expected-error {{not in class 'A' or an enclosing namespace}}
82 template<typename T
> static int A::N
<T
***>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
86 template<> struct A::C
<char>;
87 template<> void A::f
<char>();
88 template<> int A::N
<char>;
90 template<typename T
> struct A::C
<T
****>;
91 template<typename T
> int A::N
<T
****>;
94 template<> struct A::C
<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
95 template<> void A::f
<long>(); // expected-error {{not in class 'A' or an enclosing namespace}}
96 template<> int A::N
<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
98 template<typename T
> struct A::C
<T
*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
99 template<typename T
> int A::N
<T
*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
104 template<typename T
> struct C
{ typename
T::error e
; }; // expected-error {{no members}}
105 template<typename T
> void f() { T::error
; } // expected-error {{no members}}
106 template<typename T
> static const int N
= T::error
; // expected-error {{no members}} expected-error 0-1{{C++14}}
108 template<> struct C
<int> {};
109 template<> void f
<int>() {}
110 template<> static const int N
<int>;
112 template<typename T
> struct C
<T
*> {};
113 template<typename T
> static const int N
<T
*>;
117 template<> void f
<void>() {} // expected-error {{no candidate function template}}
124 int a
= D
<int>::N
<int>;
127 int b
= D
<int>::N
<int*>;
129 D
<int>::C
<float>(); // expected-note {{instantiation of}}
130 di
.f
<float>(); // expected-note {{instantiation of}}
131 int c
= D
<int>::N
<float>; // expected-note {{instantiation of}}
134 namespace mixed_inner_outer_specialization
{
135 #if __cplusplus >= 201103L
136 template<int> struct A
{
137 template<int> constexpr int f() const { return 1; }
138 template<> constexpr int f
<0>() const { return 2; }
140 template<> template<int> constexpr int A
<0>::f() const { return 3; }
141 template<> template<> constexpr int A
<0>::f
<0>() const { return 4; }
142 static_assert(A
<1>().f
<1>() == 1, "");
143 static_assert(A
<1>().f
<0>() == 2, "");
144 static_assert(A
<0>().f
<1>() == 3, "");
145 static_assert(A
<0>().f
<0>() == 4, "");
148 #if __cplusplus >= 201402L
149 template<int> struct B
{
150 template<int> static const int u
= 1;
151 template<> static const int u
<0> = 2; // expected-note {{here}}
153 // Note that in C++17 onwards, these are implicitly inline, and so the
154 // initializer of v<0> is not instantiated with the declaration. In
155 // C++14, v<0> is a non-defining declaration and its initializer is
156 // instantiated with the class.
157 template<int> static constexpr int v
= 1;
158 template<> static constexpr int v
<0> = 2; // #v0
160 template<int> static const inline int w
= 1; // expected-error 0-1{{C++17 extension}}
161 template<> static const inline int w
<0> = 2; // expected-error 0-1{{C++17 extension}}
164 template<> template<int> constexpr int B
<0>::u
= 3;
165 template<> template<> constexpr int B
<0>::u
<0> = 4; // expected-error {{already has an initializer}}
167 template<> template<int> constexpr int B
<0>::v
= 3;
168 template<> template<> constexpr int B
<0>::v
<0> = 4;
169 #if __cplusplus < 201702L
170 // expected-error@-2 {{already has an initializer}}
171 // expected-note@#v0 {{here}}
174 template<> template<int> constexpr int B
<0>::w
= 3;
175 template<> template<> constexpr int B
<0>::w
<0> = 4;
177 static_assert(B
<1>().u
<1> == 1, "");
178 static_assert(B
<1>().u
<0> == 2, "");
179 static_assert(B
<0>().u
<1> == 3, "");
181 static_assert(B
<1>().v
<1> == 1, "");
182 static_assert(B
<1>().v
<0> == 2, "");
183 static_assert(B
<0>().v
<1> == 3, "");
184 static_assert(B
<0>().v
<0> == 4, "");
185 #if __cplusplus < 201702L
186 // expected-error@-2 {{failed}} \
187 // expected-note@-2 {{evaluates to '2 == 4'}}
190 static_assert(B
<1>().w
<1> == 1, "");
191 static_assert(B
<1>().w
<0> == 2, "");
192 static_assert(B
<0>().w
<1> == 3, "");
193 static_assert(B
<0>().w
<0> == 4, "");
197 template<typename T
, typename U
> struct Collision
{
198 // FIXME: Missing diagnostic for duplicate function explicit specialization declaration.
199 template<typename
> int f1();
200 template<> int f1
<T
>();
201 template<> int f1
<U
>();
203 // FIXME: Missing diagnostic for fucntion redefinition!
204 template<typename
> int f2();
205 template<> int f2
<T
>() {}
206 template<> int f2
<U
>() {}
208 template<typename
> static int v1
; // expected-error 0-1{{C++14 extension}}
209 template<> static int v1
<T
>; // expected-note {{previous}}
210 template<> static int v1
<U
>; // expected-error {{duplicate member}}
212 template<typename
> static inline int v2
; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}}
213 template<> static inline int v2
<T
>; // expected-error 0-1{{C++17 extension}} expected-note {{previous}}
214 template<> static inline int v2
<U
>; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}}
216 // FIXME: Missing diagnostic for duplicate class explicit specialization.
217 template<typename
> struct S1
;
218 template<> struct S1
<T
>;
219 template<> struct S1
<U
>;
221 template<typename
> struct S2
;
222 template<> struct S2
<T
> {}; // expected-note {{previous}}
223 template<> struct S2
<U
> {}; // expected-error {{redefinition}}
225 Collision
<int, int> c
; // expected-note {{in instantiation of}}
228 namespace dr777
{ // dr777: 3.7
229 #if __cplusplus >= 201103L
230 template <typename
... T
>
231 void f(int i
= 0, T
...args
) {}
234 template <typename
... T
>
235 void g(int i
= 0, T
...args
, T
...args2
) {}
237 template <typename
... T
>
238 void h(int i
= 0, T
...args
, int j
= 1) {}