• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
6 
7 namespace dr705 { // dr705: yes
8   namespace N {
9     struct S {};
10     void f(S); // expected-note {{declared here}}
11   }
12 
g()13   void g() {
14     N::S s;
15     f(s);      // ok
16     (f)(s);    // expected-error {{use of undeclared}}
17   }
18 }
19 
20 namespace dr712 { // dr712: partial
21   void use(int);
f()22   void f() {
23     const int a = 0; // expected-note 5{{here}}
24     struct X {
25       void g(bool cond) {
26         use(a);
27         use((a));
28         use(cond ? a : a);
29         use((cond, a)); // expected-warning 2{{unused}} FIXME: should only warn once
30 
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 {{unused}}
35       }
36     };
37   }
38 
39 #if __cplusplus >= 201103L
g()40   void g() {
41     struct A { int n; };
42     constexpr A a = {0}; // expected-note 2{{here}}
43     struct X {
44       void g(bool cond) {
45         use(a.n);
46         use(a.*&A::n);
47 
48         (void)a.n; // FIXME: expected-error {{declared in enclosing}}
49         (void)(a.*&A::n); // FIXME: expected-error {{declared in enclosing}}
50       }
51     };
52   }
53 #endif
54 }
55 
56 namespace dr727 { // dr727: partial
57   struct A {
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}}
61 
62     template<> struct C<int>;
63     template<> void f<int>();
64     template<> static int N<int>;
65 
66     template<typename T> struct C<T*>;
67     template<typename T> static int N<T*>;
68 
69     struct B {
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}}
73 
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}}
76 
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}}
80 
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}}
83     };
84   };
85 
86   template<> struct A::C<char>;
87   template<> void A::f<char>();
88   template<> int A::N<char>;
89 
90   template<typename T> struct A::C<T****>;
91   template<typename T> int A::N<T****>;
92 
93   namespace C {
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}}
97 
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}}
100   }
101 
102   template<typename>
103   struct D {
104     template<typename T> struct C { typename T::error e; }; // expected-error {{no members}}
fdr727::D105     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}}
107 
108     template<> struct C<int> {};
fdr727::D109     template<> void f<int>() {}
110     template<> static const int N<int>;
111 
112     template<typename T> struct C<T*> {};
113     template<typename T> static const int N<T*>;
114   };
115 
d(D<int> di)116   void d(D<int> di) {
117     D<int>::C<int>();
118     di.f<int>();
119     int a = D<int>::N<int>;
120 
121     D<int>::C<int*>();
122     int b = D<int>::N<int*>;
123 
124     D<int>::C<float>(); // expected-note {{instantiation of}}
125     di.f<float>(); // expected-note {{instantiation of}}
126     int c = D<int>::N<float>; // expected-note {{instantiation of}}
127   }
128 
129   namespace mixed_inner_outer_specialization {
130 #if __cplusplus >= 201103L
131     template<int> struct A {
fdr727::mixed_inner_outer_specialization::A132       template<int> constexpr int f() const { return 1; }
fdr727::mixed_inner_outer_specialization::A133       template<> constexpr int f<0>() const { return 2; }
134     };
f() const135     template<> template<int> constexpr int A<0>::f() const { return 3; }
f() const136     template<> template<> constexpr int A<0>::f<0>() const { return 4; }
137     static_assert(A<1>().f<1>() == 1, "");
138     static_assert(A<1>().f<0>() == 2, "");
139     static_assert(A<0>().f<1>() == 3, "");
140     static_assert(A<0>().f<0>() == 4, "");
141 #endif
142 
143 #if __cplusplus >= 201402L
144     template<int> struct B {
145       template<int> static const int u = 1;
146       template<> static const int u<0> = 2; // expected-note {{here}}
147 
148       // Note that in C++17 onwards, these are implicitly inline, and so the
149       // initializer of v<0> is not instantiated with the declaration. In
150       // C++14, v<0> is a non-defining declaration and its initializer is
151       // instantiated with the class.
152       template<int> static constexpr int v = 1;
153       template<> static constexpr int v<0> = 2; // #v0
154 
155       template<int> static const inline int w = 1; // expected-error 0-1{{C++17 extension}}
156       template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}}
157     };
158 
159     template<> template<int> constexpr int B<0>::u = 3;
160     template<> template<> constexpr int B<0>::u<0> = 4; // expected-error {{already has an initializer}}
161 
162     template<> template<int> constexpr int B<0>::v = 3;
163     template<> template<> constexpr int B<0>::v<0> = 4;
164 #if __cplusplus < 201702L
165     // expected-error@-2 {{already has an initializer}}
166     // expected-note@#v0 {{here}}
167 #endif
168 
169     template<> template<int> constexpr int B<0>::w = 3;
170     template<> template<> constexpr int B<0>::w<0> = 4;
171 
172     static_assert(B<1>().u<1> == 1, "");
173     static_assert(B<1>().u<0> == 2, "");
174     static_assert(B<0>().u<1> == 3, "");
175 
176     static_assert(B<1>().v<1> == 1, "");
177     static_assert(B<1>().v<0> == 2, "");
178     static_assert(B<0>().v<1> == 3, "");
179     static_assert(B<0>().v<0> == 4, "");
180 #if __cplusplus < 201702L
181     // expected-error@-2 {{failed}}
182 #endif
183 
184     static_assert(B<1>().w<1> == 1, "");
185     static_assert(B<1>().w<0> == 2, "");
186     static_assert(B<0>().w<1> == 3, "");
187     static_assert(B<0>().w<0> == 4, "");
188 #endif
189   }
190 
191   template<typename T, typename U> struct Collision {
192     // FIXME: Missing diagnostic for duplicate function explicit specialization declaration.
193     template<typename> int f1();
194     template<> int f1<T>();
195     template<> int f1<U>();
196 
197     // FIXME: Missing diagnostic for fucntion redefinition!
198     template<typename> int f2();
f2dr727::Collision199     template<> int f2<T>() {}
f2dr727::Collision200     template<> int f2<U>() {}
201 
202     template<typename> static int v1; // expected-error 0-1{{C++14 extension}}
203     template<> static int v1<T>; // expected-note {{previous}}
204     template<> static int v1<U>; // expected-error {{duplicate member}}
205 
206     template<typename> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}}
207     template<> static inline int v2<T>;      // expected-error 0-1{{C++17 extension}} expected-note {{previous}}
208     template<> static inline int v2<U>;      // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}}
209 
210     // FIXME: Missing diagnostic for duplicate class explicit specialization.
211     template<typename> struct S1;
212     template<> struct S1<T>;
213     template<> struct S1<U>;
214 
215     template<typename> struct S2;
216     template<> struct S2<T> {}; // expected-note {{previous}}
217     template<> struct S2<U> {}; // expected-error {{redefinition}}
218   };
219   Collision<int, int> c; // expected-note {{in instantiation of}}
220 }
221 
222 namespace dr777 { // dr777: 3.7
223 #if __cplusplus >= 201103L
224 template <typename... T>
f(int i=0,T...args)225 void f(int i = 0, T ...args) {}
ff()226 void ff() { f(); }
227 
228 template <typename... T>
g(int i=0,T...args,T...args2)229 void g(int i = 0, T ...args, T ...args2) {}
230 
231 template <typename... T>
h(int i=0,T...args,int j=1)232 void h(int i = 0, T ...args, int j = 1) {}
233 #endif
234 }
235