1 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
2 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
3 
4 auto f(); // expected-note {{previous}}
5 int f(); // expected-error {{differ only in their return type}}
6 
7 auto &g();
8 auto g() -> auto &;
9 
10 auto h() -> auto *;
11 auto *h();
12 
13 struct Conv1 {
14   operator auto(); // expected-note {{declared here}}
15 } conv1;
16 int conv1a = conv1; // expected-error {{function 'operator auto' with deduced return type cannot be used before it is defined}}
17 // expected-error@-1 {{no viable conversion}}
operator auto()18 Conv1::operator auto() { return 123; }
19 int conv1b = conv1;
20 int conv1c = conv1.operator auto();
21 int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}}
22 
23 struct Conv2 {
operator autoConv224   operator auto() { return 0; }  // expected-note {{previous}}
operator autoConv225   operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{cannot initialize return object of type 'auto' with an rvalue of type 'double'}}
26 };
27 
28 struct Conv3 {
operator autoConv329   operator auto() { int *p = nullptr; return p; }  // expected-note {{candidate}}
operator auto*Conv330   operator auto*() { int *p = nullptr; return p; } // expected-note {{candidate}}
31 } conv3;
32 int *conv3a = conv3; // expected-error {{ambiguous}}
33 int *conv3b = conv3.operator auto();
34 int *conv3c = conv3.operator auto*();
35 
36 template<typename T>
37 struct Conv4 {
operator autoConv438   operator auto() { return T(); }
39 };
40 Conv4<int> conv4int;
41 int conv4a = conv4int;
42 int conv4b = conv4int.operator auto();
43 
44 auto a();
a()45 auto a() { return 0; }
46 using T = decltype(a());
47 using T = int;
48 auto a(); // expected-note {{previous}}
49 using T = decltype(a());
50 auto *a(); // expected-error {{differ only in their return type}}
51 
b(bool k)52 auto b(bool k) {
53   if (k)
54     return "hello";
55   return "goodbye";
56 }
57 
58 // Allow 'operator auto' to call only the explicit operator auto.
59 struct BothOps {
60   template <typename T> operator T();
61   template <typename T> operator T *();
operator autoBothOps62   operator auto() { return 0; }
operator auto*BothOps63   operator auto *() { return this; }
64 };
65 struct JustTemplateOp {
66   template <typename T> operator T();
67   template <typename T> operator T *();
68 };
69 
c()70 auto c() {
71   BothOps().operator auto(); // ok
72   BothOps().operator auto *(); // ok
73   JustTemplateOp().operator auto(); // expected-error {{no member named 'operator auto' in 'JustTemplateOp'}}
74   JustTemplateOp().operator auto *(); // expected-error {{no member named 'operator auto *' in 'JustTemplateOp'}}
75 }
76 
ptr_1()77 auto *ptr_1() {
78   return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}}
79 }
80 
ref_1()81 const auto &ref_1() {
82   return 0; // expected-warning {{returning reference to local temporary}}
83 }
84 
init_list()85 auto init_list() {
86   return { 1, 2, 3 }; // expected-error {{cannot deduce return type from initializer list}}
87 }
88 
89 auto fwd_decl(); // expected-note 2{{here}}
90 
91 int n = fwd_decl(); // expected-error {{function 'fwd_decl' with deduced return type cannot be used before it is defined}}
92 int k = sizeof(fwd_decl()); // expected-error {{used before it is defined}}
93 
fac(int n)94 auto fac(int n) {
95   if (n <= 2)
96     return n;
97   return n * fac(n-1); // ok
98 }
99 
fac_2(int n)100 auto fac_2(int n) { // expected-note {{declared here}}
101   if (n > 2)
102     return n * fac_2(n-1); // expected-error {{cannot be used before it is defined}}
103   return n;
104 }
105 
void_ret()106 auto void_ret() {}
107 using Void = void;
108 using Void = decltype(void_ret());
109 
void_ret_2()110 auto &void_ret_2() {} // expected-error {{cannot deduce return type 'auto &' for function with no return statements}}
void_ret_3()111 const auto void_ret_3() {} // ok, return type 'const void' is adjusted to 'void'
112 
void_ret_4()113 const auto void_ret_4() {
114   if (false)
115     return void();
116   if (false)
117     return;
118   return 0; // expected-error {{'auto' in return type deduced as 'int' here but deduced as 'void' in earlier return statement}}
119 }
120 
121 namespace Templates {
f1()122   template<typename T> auto f1() {
123     return T() + 1;
124   }
f2(T && v)125   template<typename T> auto &f2(T &&v) { return v; }
126   int a = f1<int>();
127   const int &b = f2(0);
128   double d;
129   float &c = f2(0.0); // expected-error {{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'double'}}
130 
131   template<typename T> auto fwd_decl(); // expected-note {{declared here}}
132   int e = fwd_decl<int>(); // expected-error {{cannot be used before it is defined}}
fwd_decl()133   template<typename T> auto fwd_decl() { return 0; }
134   int f = fwd_decl<int>();
135   template <typename T>
136   auto fwd_decl(); // expected-note {{candidate template ignored: could not match 'auto ()' against 'int ()'}}
137   int g = fwd_decl<char>();
138 
139   auto (*p)() = f1; // expected-error {{incompatible initializer}}
140   auto (*q)() = f1<int>; // ok
141 
142   typedef decltype(f2(1.2)) dbl; // expected-note {{previous}}
143   typedef float dbl; // expected-error {{typedef redefinition with different types ('float' vs 'decltype(f2(1.2))' (aka 'double &'))}}
144 
145   extern template auto fwd_decl<double>();
146   int k1 = fwd_decl<double>();
147   extern template int fwd_decl<char>(); // expected-error {{does not refer to a function template}}
148   int k2 = fwd_decl<char>();
149 
instantiate()150   template <typename T> auto instantiate() { T::error; } // expected-error {{has no members}} \
151     // expected-note {{candidate template ignored: could not match 'auto ()' against 'void ()'}}
152   extern template auto instantiate<int>(); // ok
153   int k = instantiate<int>(); // expected-note {{in instantiation of}}
instantiate()154   template<> auto instantiate<char>() {} // ok
instantiate()155   template<> void instantiate<double>() {} // expected-error {{no function template matches}}
156 
arg_single()157   template<typename T> auto arg_single() { return 0; }
arg_multi()158   template<typename T> auto arg_multi() { return 0l; }
arg_multi(int)159   template<typename T> auto arg_multi(int) { return "bad"; }
160   template<typename T> struct Outer {
arg_singleTemplates::Outer161     static auto arg_single() { return 0.f; }
arg_multiTemplates::Outer162     static auto arg_multi() { return 0.; }
arg_multiTemplates::Outer163     static auto arg_multi(int) { return "bad"; }
164   };
165   template<typename T> T &take_fn(T (*p)());
166 
167   int &check1 = take_fn(arg_single); // expected-error {{no matching}} expected-note@-2 {{couldn't infer}}
168   int &check2 = take_fn(arg_single<int>);
169   int &check3 = take_fn<int>(arg_single); // expected-error {{no matching}} expected-note@-4{{no overload of 'arg_single'}}
170   int &check4 = take_fn<int>(arg_single<int>);
171   long &check5 = take_fn(arg_multi); // expected-error {{no matching}} expected-note@-6 {{couldn't infer}}
172   long &check6 = take_fn(arg_multi<int>);
173   long &check7 = take_fn<long>(arg_multi); // expected-error {{no matching}} expected-note@-8{{no overload of 'arg_multi'}}
174   long &check8 = take_fn<long>(arg_multi<int>);
175 
176   float &mem_check1 = take_fn(Outer<int>::arg_single);
177   float &mem_check2 = take_fn<float>(Outer<char>::arg_single);
178   double &mem_check3 = take_fn(Outer<long>::arg_multi);
179   double &mem_check4 = take_fn<double>(Outer<double>::arg_multi);
180 
181   namespace Deduce1 {
f()182   template <typename T> auto f() { return 0; } // expected-note {{couldn't infer template argument 'T'}}
183     template<typename T> void g(T(*)()); // expected-note 2{{candidate}}
h()184     void h() {
185       auto p = f<int>;
186       auto (*q)() = f<int>;
187       int (*r)() = f; // expected-error {{does not match}}
188       g(f<int>);
189       g<int>(f); // expected-error {{no matching function}}
190       g(f); // expected-error {{no matching function}}
191     }
192   }
193 
194   namespace Deduce2 {
f(int)195   template <typename T> auto f(int) { return 0; } // expected-note {{couldn't infer template argument 'T'}}
196     template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}}
h()197     void h() {
198       auto p = f<int>;
199       auto (*q)(int) = f<int>;
200       int (*r)(int) = f; // expected-error {{does not match}}
201       g(f<int>);
202       g<int>(f); // expected-error {{no matching function}}
203       g(f); // expected-error {{no matching function}}
204     }
205   }
206 
207   namespace Deduce3 {
f(T)208     template<typename T> auto f(T) { return 0; }
209     template<typename T> void g(T(*)(int)); // expected-note {{couldn't infer}}
h()210     void h() {
211       auto p = f<int>;
212       auto (*q)(int) = f<int>;
213       int (*r)(int) = f; // ok
214       g(f<int>);
215       g<int>(f); // ok
216       g(f); // expected-error {{no matching function}}
217     }
218   }
219 
220   namespace DeduceInDeducedReturnType {
f()221     template<typename T, typename U> auto f() -> auto (T::*)(U) {
222       int (T::*result)(U) = nullptr;
223       return result;
224     }
225     struct S {};
226     int (S::*(*p)())(double) = f;
227     int (S::*(*q)())(double) = f<S, double>;
228   }
229 }
230 
231 auto fwd_decl_using();
232 namespace N { using ::fwd_decl_using; }
fwd_decl_using()233 auto fwd_decl_using() { return 0; }
234 namespace N { int k = N::fwd_decl_using(); }
235 
236 namespace OverloadResolutionNonTemplate {
237   auto f();
238   auto f(int); // expected-note {{here}}
239 
240   int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}}
241   char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}}
242 
243   int a = g(f); // expected-error {{no matching function}}
244 
f()245   auto f() { return 0; }
246 
247   // FIXME: It's not completely clear whether this should be ill-formed.
248   int &b = g(f); // expected-error {{used before it is defined}}
249 
f(int)250   auto f(int) { return 0.0; }
251 
252   int &c = g(f); // ok
253 }
254 
255 namespace OverloadResolutionTemplate {
256   auto f();
257   template<typename T> auto f(T);
258 
259   int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}} expected-note {{candidate}}
260   char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}} expected-note {{candidate}}
261 
262   int a = g(f); // expected-error {{no matching function}}
263 
f()264   auto f() { return 0; }
265 
266   int &b = g(f); // ok (presumably), due to deduction failure forming type of 'f<int>'
267 
f(T)268   template<typename T> auto f(T) { return 0; }
269 
270   int &c = g(f); // expected-error {{ambiguous}}
271 }
272 
273 namespace DefaultedMethods {
274   struct A {
275     auto operator=(const A&) = default; // expected-error {{must return 'DefaultedMethods::A &'}}
276     A &operator=(A&&); // expected-note {{previous}}
277   };
278   auto A::operator=(A&&) = default; // expected-error {{return type of out-of-line definition of 'DefaultedMethods::A::operator=' differs from that in the declaration}}
279 }
280 
281 namespace Constexpr {
f1(int n)282   constexpr auto f1(int n) { return n; }
fConstexpr::X283   template<typename T> struct X { constexpr auto f() {} }; // PR18746
fConstexpr::Y284   template<typename T> struct Y { constexpr T f() {} }; // expected-note {{control reached end of constexpr function}}
f()285   void f() {
286     X<int>().f();
287     Y<void>().f();
288     constexpr int q = Y<int>().f(); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to '&Y<int>()->f()'}}
289   }
290   struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
f2(int n)291   constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
292 }
293 
294 // It's not really clear whether these are valid, but this matches g++.
295 using size_t = decltype(sizeof(0));
296 auto operator new(size_t n, const char*); // expected-error {{must return type 'void *'}}
297 auto operator delete(void *, const char*); // expected-error {{must return type 'void'}}
298 
299 namespace Virtual {
300   struct S {
fVirtual::S301     virtual auto f() { return 0; } // expected-error {{function with deduced return type cannot be virtual}} expected-note {{here}}
302   };
303   // Allow 'auto' anyway for error recovery.
304   struct T : S {
305     int f();
306   };
307   struct U : S {
308     auto f(); // expected-error {{different return}}
309   };
310 
311   // And here's why...
312   struct V { virtual auto f(); }; // expected-error {{cannot be virtual}}
313   struct W : V { virtual auto f(); }; // expected-error {{cannot be virtual}}
f()314   auto V::f() { return 0; } // in tu1.cpp
f()315   auto W::f() { return 0.0; } // in tu2.cpp
316   W w;
317   int k1 = w.f();
318   int k2 = ((V&)w).f();
319 }
320 
321 namespace std_examples {
322 
323 namespace NoReturn {
f()324   auto f() {}
325   void (*p)() = &f;
326 
327   auto f(); // ok
328 
g()329   auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}}
330 
331   auto h() = delete; // expected-note {{explicitly deleted}}
332   auto x = h(); // expected-error {{call to deleted}}
333 }
334 
335 namespace UseBeforeComplete {
336   auto n = n; // expected-error {{variable 'n' declared with deduced type 'auto' cannot appear in its own initializer}}
337   auto f(); // expected-note {{declared here}}
g()338   void g() { &f; } // expected-error {{function 'f' with deduced return type cannot be used before it is defined}}
sum(int i)339   auto sum(int i) {
340     if (i == 1)
341       return i;
342     else
343       return sum(i - 1) + i;
344   }
345 }
346 
347 namespace Redecl {
348   auto f();
f()349   auto f() { return 42; }
350   auto f(); // expected-note 2{{previous}}
351   int f(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
352   decltype(auto) f(); // expected-error {{cannot be overloaded}}
353 
g(T t)354   template <typename T> auto g(T t) { return t; } // expected-note {{candidate}} \
355                                                   // expected-note {{candidate function [with T = int]}}
356   template auto g(int);
357   template char g(char); // expected-error {{does not refer to a function}}
358   template<> auto g(double);
359 
g(T t)360   template<typename T> T g(T t) { return t; } // expected-note {{candidate}}
361   template char g(char);
362   template auto g(float);
363 
h()364   void h() { return g(42); } // expected-error {{ambiguous}}
365 }
366 
367 namespace ExplicitInstantiationDecl {
f(T t)368   template<typename T> auto f(T t) { return t; }
369   extern template auto f(int);
370   int (*p)(int) = f;
371 }
372 namespace MemberTemplatesWithDeduction {
373   struct M {
foostd_examples::MemberTemplatesWithDeduction::M374     template<class T> auto foo(T t) { return t; }
operator ()std_examples::MemberTemplatesWithDeduction::M375     template<class T> auto operator()(T t) const { return t; }
static_foostd_examples::MemberTemplatesWithDeduction::M376     template<class T> static __attribute__((unused)) int static_foo(T) {
377       return 5;
378     }
operator Tstd_examples::MemberTemplatesWithDeduction::M379     template<class T> operator T() { return T{}; }
operator autostd_examples::MemberTemplatesWithDeduction::M380     operator auto() { return &static_foo<int>; }
381   };
382   struct N : M {
383     using M::foo;
384     using M::operator();
385     using M::static_foo;
386     using M::operator auto;
387   };
388 
test()389   template <class T> int test() {
390     int i = T{}.foo(3);
391     T m = T{}.foo(M{});
392     int j = T{}(3);
393     M m2 = M{}(M{});
394     int k = T{}.static_foo(4);
395     int l = T::static_foo(5);
396     int l2 = T{};
397     struct X { };
398     X x = T{};
399     return 0;
400   }
401   int Minst = test<M>();
402   int Ninst = test<N>();
403 
404 }
405 }
406 
407 // We resolve a wording bug here: 'decltype(auto)' should not be modeled as a
408 // decltype-specifier, just as a simple-type-specifier. All the extra places
409 // where a decltype-specifier can appear make no sense for 'decltype(auto)'.
410 namespace DecltypeAutoShouldNotBeADecltypeSpecifier {
411   namespace NNS {
412     int n;
413     decltype(auto) i();
414     decltype(n) j();
415     struct X {
416       friend decltype(auto) ::DecltypeAutoShouldNotBeADecltypeSpecifier::NNS::i();
417       friend decltype(n) ::DecltypeAutoShouldNotBeADecltypeSpecifier::NNS::j(); // expected-error {{not a class}}
418     };
419   }
420 
421   namespace Dtor {
422     struct A {};
f(A a)423     void f(A a) { a.~decltype(auto)(); } // expected-error {{'decltype(auto)' not allowed here}}
424   }
425 
426   namespace BaseClass {
427     struct A : decltype(auto) {}; // expected-error {{'decltype(auto)' not allowed here}}
428     struct B {
BDecltypeAutoShouldNotBeADecltypeSpecifier::BaseClass::B429       B() : decltype(auto)() {} // expected-error {{'decltype(auto)' not allowed here}}
430     };
431   }
432 }
433 
434 namespace CurrentInstantiation {
435   // PR16875
436   template<typename T> struct S {
fCurrentInstantiation::S437     auto f() { return T(); }
gCurrentInstantiation::S438     int g() { return f(); }
hCurrentInstantiation::S439     auto h(bool b) {
440       if (b)
441         return T();
442       return h(true);
443     }
444   };
445   int k1 = S<int>().g();
446   int k2 = S<int>().h(false);
447 
448   template<typename T> struct U {
449  #ifndef DELAYED_TEMPLATE_PARSING
450     auto f(); // expected-note {{here}}
gCurrentInstantiation::U451     int g() { return f(); } // expected-error {{cannot be used before it is defined}}
452  #else
453     auto f();
454     int g() { return f(); }
455  #endif
456   };
457  #ifndef DELAYED_TEMPLATE_PARSING
458   template int U<int>::g(); // expected-note {{in instantiation of}}
459  #else
460   template int U<int>::g();
461  #endif
f()462   template<typename T> auto U<T>::f() { return T(); }
463   template int U<short>::g(); // ok
464 }
465 
466 namespace WithDefaultArgs {
467   template<typename U> struct A {
f(A)468     template<typename T = U> friend auto f(A) { return []{}; }
469   };
470   template<typename T> void f();
471   using T = decltype(f(A<int>()));
472   using T = decltype(f<int>(A<int>()));
473 }
474 
475 namespace MultilevelDeduction {
476 
F()477 auto F() -> auto* { return (int*)0; }
478 
G()479 auto (*G())() -> int* { return F; }
480 
481 auto run = G();
482 
483 namespace Templated {
484 template<class T>
F(T t)485 auto F(T t) -> auto* { return (T*)0; }
486 
487 template<class T>
G(T t)488 auto (*G(T t))(T) -> T* { return &F<T>; }
489 
490 
491 template<class T>
G2(T t)492 auto (*G2(T t))(T) -> auto* { return &F<T>; }
493 
494 auto run_int = G(1);
495 auto run_char = G2('a');
496 
497 }
498 }
499 
500 namespace rnk {
501 extern "C" int puts(const char *s);
502 template <typename T>
foo(T x)503 auto foo(T x) -> decltype(x) {
504 #ifdef DELAYED_TEMPLATE_PARSING
505   ::rnk::bar();
506 #endif
507   return x;
508 }
bar()509 void bar() { puts("bar"); }
main()510 int main() { return foo(0); }
511 
512 }
513 
514 namespace OverloadedOperators {
515   template<typename T> struct A {
operator ()OverloadedOperators::A516     auto operator()() { return T{}; }
operator []OverloadedOperators::A517     auto operator[](int) { return T{}; }
operator +OverloadedOperators::A518     auto operator+(int) { return T{}; }
operator +OverloadedOperators::A519     auto operator+() { return T{}; }
operator -(A)520     friend auto operator-(A) { return T{}; }
operator -(A,A)521     friend auto operator-(A, A) { return T{}; }
522   };
f(A<int> a)523   void f(A<int> a) {
524     int b = a();
525     int c = a[0];
526     int d = a + 0;
527     int e = +a;
528     int f = -a;
529     int g = a - a;
530   }
531 }
532 
533 namespace TrailingReturnTypeForConversionOperator {
534   struct X {
operator autoTrailingReturnTypeForConversionOperator::X535     operator auto() -> int { return 0; } // expected-error {{cannot specify any part of a return type in the declaration of a conversion function; put the complete type after 'operator'}}
536   } x;
537   int k = x.operator auto();
538 
539   struct Y {
operator autoTrailingReturnTypeForConversionOperator::Y540     operator auto() -> int & { // expected-error {{cannot specify}}
541       return 0; // expected-error {{cannot bind to}}
542     }
543   };
544 };
545 
546 namespace PR24989 {
__anon8105ed8d0202(auto)547   auto x = [](auto){};
548   using T = decltype(x);
549   void (T::*p)(int) const = &T::operator();
550 }
551 
forinit_decltypeauto()552 void forinit_decltypeauto() {
553   for (decltype(auto) forinit_decltypeauto_inner();;) {} // expected-warning {{interpreted as a function}} expected-note {{replace}}
554 }
555 
556 namespace PR33222 {
557   auto f1();
558   auto f2();
559 
g0(T x)560   template<typename T> decltype(auto) g0(T x) { return x.n; }
561   template<typename T> decltype(auto) g1(T);
562   template<typename T> decltype(auto) g2(T);
563 
564   struct X {
565     static auto f1();
566     static auto f2();
567 
g0PR33222::X568     template<typename T> static decltype(auto) g0(T x) { return x.n; }
569     template<typename T> static decltype(auto) g1(T);
570     template<typename T> static decltype(auto) g2(T);
571   };
572 
573   template<typename U> class A {
574     friend auto f1();
575     friend auto f2();
576 
577     friend decltype(auto) g0<>(A);
578     template<typename T> friend decltype(auto) g1(T);
579     template<typename T> friend decltype(auto) g2(T);
580 
581     friend auto X::f1();
582     friend auto X::f2();
583 
584     // FIXME (PR38882): 'A' names the class template not the injected-class-name here!
585     friend decltype(auto) X::g0<>(A<U>);
586     // FIXME (PR38882): ::T hides the template parameter if both are named T here!
587     template<typename T_> friend decltype(auto) X::g1(T_);
588     template<typename T_> friend decltype(auto) X::g2(T_);
589 
590     int n;
591   };
592 
f1()593   auto f1() { return A<int>().n; }
g1(T x)594   template<typename T> decltype(auto) g1(T x) { return A<int>().n; }
595 
f1()596   auto X::f1() { return A<int>().n; }
g1(T x)597   template<typename T> decltype(auto) X::g1(T x) { return A<int>().n; }
598 
599   A<int> ai;
600   int k1 = g0(ai);
601   int k2 = X::g0(ai);
602 
603   int k3 = g1(ai);
604   int k4 = X::g1(ai);
605 
f2()606   auto f2() { return A<int>().n; }
g2(T x)607   template<typename T> decltype(auto) g2(T x) { return A<int>().n; }
608 
f2()609   auto X::f2() { return A<int>().n; }
g2(T x)610   template<typename T> decltype(auto) X::g2(T x) { return A<int>().n; }
611 
612   int k5 = g2(ai);
613   int k6 = X::g2(ai);
614 
615   template<typename> struct B {
qPR33222::B616     auto *q() { return (float*)0; } // expected-note 2{{previous}}
617   };
q()618   template<> auto *B<char[1]>::q() { return (int*)0; }
q()619   template<> auto B<char[2]>::q() { return (int*)0; } // expected-error {{return type}}
620   // FIXME: suppress this follow-on error: expected-error@-1 {{cannot initialize}}
q()621   template<> int B<char[3]>::q() { return 0; } // expected-error {{return type}}
622 }
623