xref: /llvm-project/clang/test/Parser/cxx-ambig-init-templ.cpp (revision b3f6e3d6d64d77a9c840b8407b7e3c49b62b46dd)
1406e65c8SRichard Trieu // RUN: %clang_cc1 -Wno-uninitialized -std=c++11 -verify %s
21fff95c7SRichard Smith 
31fff95c7SRichard Smith template<int> struct c { c(int) = delete; typedef void val; operator int() const; };
41fff95c7SRichard Smith 
5*b3f6e3d6SRichard Smith int f;
61fff95c7SRichard Smith int val;
71fff95c7SRichard Smith int foobar;
81fff95c7SRichard Smith struct S {
91fff95c7SRichard Smith   int k1 = a < b < c, d > ::val, e1;
101fff95c7SRichard Smith   int k2 = a < b, c < d > ::val, e2;
111fff95c7SRichard Smith   int k3 = b < a < c, d > ::val, e3;
121fff95c7SRichard Smith   int k4 = b < c, x, y = d > ::val, e4;
131fff95c7SRichard Smith   int k5 = T1 < b, &S::operator=(int); // expected-error {{extra qualification}}
141fff95c7SRichard Smith   int k6 = T2 < b, &S::operator= >::val;
151fff95c7SRichard Smith   int k7 = T1 < b, &S::operator>(int); // expected-error {{extra qualification}}
161fff95c7SRichard Smith   int k8 = T2 < b, &S::operator> >::val;
171fff95c7SRichard Smith   int k9 = T3 < a < b, c >> (d), e5 = 1 > (e4);
181fff95c7SRichard Smith   int k10 = 0 < T3 < a < b, c >> (d
191fff95c7SRichard Smith       ) // expected-error {{expected ';' at end of declaration}}
201fff95c7SRichard Smith       , a > (e4);
211fff95c7SRichard Smith   int k11 = 0 < 1, c<3>::*ptr;
221fff95c7SRichard Smith   int k12 = e < 0, int a<b<c>::* >(), e11;
231fff95c7SRichard Smith 
241fff95c7SRichard Smith   void f1(
251fff95c7SRichard Smith     int k1 = a < b < c, d > ::val,
261fff95c7SRichard Smith     int k2 = b < a < c, d > ::val,
271fff95c7SRichard Smith     int k3 = b < c, int x = 0 > ::val,
281fff95c7SRichard Smith     int k4 = a < b, T3 < int > >(), // expected-error {{must be an expression}}
291fff95c7SRichard Smith     int k5 = a < b, c < d > ::val,
301fff95c7SRichard Smith     int k6 = a < b, c < d > (n) // expected-error {{undeclared identifier 'n'}}
311fff95c7SRichard Smith   );
321fff95c7SRichard Smith 
33*b3f6e3d6SRichard Smith   static void f1b(
34*b3f6e3d6SRichard Smith     int k6 = a < b, c < d > (f)
35*b3f6e3d6SRichard Smith   );
36*b3f6e3d6SRichard Smith   using f1b_T = decltype(f1b(0)); // only one parameter, because second param
37*b3f6e3d6SRichard Smith                                   // would be missing its default argument
38*b3f6e3d6SRichard Smith 
391fff95c7SRichard Smith   void f2a(
401fff95c7SRichard Smith     // T3<int> here is a parameter type, so must be declared before it is used.
41b23c5e8cSRichard Smith     int k1 = c < b, T3 < int > x = 0 // expected-error {{no template named 'T3'}}
421fff95c7SRichard Smith   );
431fff95c7SRichard Smith 
441fff95c7SRichard Smith   template<typename, int=0> struct T3 { T3(int); operator int(); };
451fff95c7SRichard Smith 
461fff95c7SRichard Smith   void f2b(
471fff95c7SRichard Smith     int k1 = c < b, T3 < int > x  = 0 // ok
481fff95c7SRichard Smith   );
491fff95c7SRichard Smith 
501fff95c7SRichard Smith   // This is a one-parameter function. Ensure we don't typo-correct it to
511fff95c7SRichard Smith   //     int = a < b, c < foobar > ()
521fff95c7SRichard Smith   // ... which would be a function with two parameters.
531fff95c7SRichard Smith   int f3(int = a < b, c < goobar > ());
541fff95c7SRichard Smith   static constexpr int (S::*f3_test)(int) = &S::f3;
551fff95c7SRichard Smith 
561fff95c7SRichard Smith   void f4(
571fff95c7SRichard Smith     int k1 = a<1,2>::val,
581fff95c7SRichard Smith     int missing_default // expected-error {{missing default argument on parameter}}
591fff95c7SRichard Smith   );
601fff95c7SRichard Smith 
611fff95c7SRichard Smith   void f5(
621fff95c7SRichard Smith     int k1 = b < c,
631fff95c7SRichard Smith     int missing_default // expected-error {{missing default argument on parameter}}
641fff95c7SRichard Smith   );
651fff95c7SRichard Smith 
66*b3f6e3d6SRichard Smith   // FIXME: We should ideally disambiguate this as two parameters.
671fff95c7SRichard Smith   void f6(
68*b3f6e3d6SRichard Smith     int k = b < c, // expected-error {{unexpected end of default argument}}
69*b3f6e3d6SRichard Smith     unsigned int (missing_default)
701fff95c7SRichard Smith   );
711fff95c7SRichard Smith 
72*b3f6e3d6SRichard Smith   template<int, int = 0> struct a { // expected-note {{here}}
73*b3f6e3d6SRichard Smith     a();
74*b3f6e3d6SRichard Smith     a(int);
75*b3f6e3d6SRichard Smith     static const int val = 0;
76*b3f6e3d6SRichard Smith     operator int();
77*b3f6e3d6SRichard Smith   };
781fff95c7SRichard Smith   static const int b = 0, c = 1, d = 2, goobar = 3;
791fff95c7SRichard Smith   template<int, typename> struct e { operator int(); };
80*b3f6e3d6SRichard Smith   static const int f = 0;
811fff95c7SRichard Smith 
821fff95c7SRichard Smith   int mp1 = 0 < 1,
831fff95c7SRichard Smith       a<b<c,b<c>::*mp2,
841fff95c7SRichard Smith       mp3 = 0 > a<b<c>::val,
851fff95c7SRichard Smith       a<b<c,b<c>::*mp4 = 0,
861fff95c7SRichard Smith       a<b<c,b<c>::*mp5 {0},
871fff95c7SRichard Smith       a<b<c,b<c>::*mp6;
881fff95c7SRichard Smith 
891fff95c7SRichard Smith   int np1 = e<0, int a<b<c,b<c>::*>();
901fff95c7SRichard Smith 
911fff95c7SRichard Smith   static const int T1 = 4;
921fff95c7SRichard Smith   template<int, int &(S::*)(int)> struct T2 { static const int val = 0; };
931fff95c7SRichard Smith };
941fff95c7SRichard Smith 
951fff95c7SRichard Smith namespace NoAnnotationTokens {
961fff95c7SRichard Smith   template<bool> struct Bool { Bool(int); };
971fff95c7SRichard Smith   static const bool in_class = false;
981fff95c7SRichard Smith 
991fff95c7SRichard Smith   struct Test {
1001fff95c7SRichard Smith     // Check we don't keep around a Bool<false> annotation token here.
1011fff95c7SRichard Smith     int f(Bool<true> = X<Y, Bool<in_class> >(0));
1021fff95c7SRichard Smith 
1031fff95c7SRichard Smith     // But it's OK if we do here.
1041fff95c7SRichard Smith     int g(Bool<true> = Z<Y, Bool<in_class> = Bool<false>(0));
1051fff95c7SRichard Smith 
1061fff95c7SRichard Smith     static const bool in_class = true;
1071fff95c7SRichard Smith     template<int, typename U> using X = U;
1081fff95c7SRichard Smith     static const int Y = 0, Z = 0;
1091fff95c7SRichard Smith   };
1101fff95c7SRichard Smith }
1111fff95c7SRichard Smith 
1121fff95c7SRichard Smith namespace ImplicitInstantiation {
1131fff95c7SRichard Smith   template<typename T> struct HasError { typename T::error error; }; // expected-error {{has no members}}
1141fff95c7SRichard Smith 
1151fff95c7SRichard Smith   struct S {
1161fff95c7SRichard Smith     // This triggers the instantiation of the outer HasError<int> during
1171fff95c7SRichard Smith     // disambiguation, even though it uses the inner HasError<int>.
1181fff95c7SRichard Smith     void f(int a = X<Y, HasError<int>::Z >()); // expected-note {{in instantiation of}}
1191fff95c7SRichard Smith 
1201fff95c7SRichard Smith     template<typename, typename> struct X { operator int(); };
1211fff95c7SRichard Smith     typedef int Y;
1221fff95c7SRichard Smith     template<typename> struct HasError { typedef int Z; };
1231fff95c7SRichard Smith   };
1241fff95c7SRichard Smith 
1251fff95c7SRichard Smith   HasError<int> hei;
1261fff95c7SRichard Smith }
1271fff95c7SRichard Smith 
1281fff95c7SRichard Smith namespace CWG325 {
1291fff95c7SRichard Smith   template <int A, typename B> struct T { static int i; operator int(); };
1301fff95c7SRichard Smith   class C {
1311fff95c7SRichard Smith     int Foo (int i = T<1, int>::i);
1321fff95c7SRichard Smith   };
1331fff95c7SRichard Smith 
1341fff95c7SRichard Smith   class D {
1351fff95c7SRichard Smith     int Foo (int i = T<1, int>::i);
1361fff95c7SRichard Smith     template <int A, typename B> struct T {static int i;};
1371fff95c7SRichard Smith   };
1381fff95c7SRichard Smith 
1391fff95c7SRichard Smith   const int a = 0;
1401fff95c7SRichard Smith   typedef int b;
1411fff95c7SRichard Smith   T<a,b> c;
1421fff95c7SRichard Smith   struct E {
1431fff95c7SRichard Smith     int n = T<a,b>(c);
1441fff95c7SRichard Smith   };
1451fff95c7SRichard Smith }
1461fff95c7SRichard Smith 
1471fff95c7SRichard Smith namespace Operators {
1481fff95c7SRichard Smith   struct Y {};
operator ,(const Y &,const Y &)1491fff95c7SRichard Smith   constexpr int operator,(const Y&, const Y&) { return 8; }
operator >(const Y &,const Y &)1501fff95c7SRichard Smith   constexpr int operator>(const Y&, const Y&) { return 8; }
operator <(const Y &,const Y &)1511fff95c7SRichard Smith   constexpr int operator<(const Y&, const Y&) { return 8; }
operator >>(const Y &,const Y &)1521fff95c7SRichard Smith   constexpr int operator>>(const Y&, const Y&) { return 8; }
1531fff95c7SRichard Smith 
1541fff95c7SRichard Smith   struct X {
1551fff95c7SRichard Smith     typedef int (*Fn)(const Y&, const Y&);
1561fff95c7SRichard Smith 
1571fff95c7SRichard Smith     Fn a = operator,, b = operator<, c = operator>;
1581fff95c7SRichard Smith     void f(Fn a = operator,, Fn b = operator<, Fn c = operator>);
1591fff95c7SRichard Smith 
1601fff95c7SRichard Smith     int k1 = T1<0, operator<, operator>, operator<>::val, l1;
1611fff95c7SRichard Smith     int k2 = T1<0, operator>, operator,, operator,>::val, l2;
1621fff95c7SRichard Smith     int k3 = T2<0, operator,(Y{}, Y{}),  operator<(Y{}, Y{})>::val, l3;
1631fff95c7SRichard Smith     int k4 = T2<0, operator>(Y{}, Y{}),  operator,(Y{}, Y{})>::val, l4;
1641fff95c7SRichard Smith     int k5 = T3<0, operator>>>::val, l5;
1651fff95c7SRichard Smith     int k6 = T4<0, T3<0, operator>>>>::val, l6;
1661fff95c7SRichard Smith 
1671fff95c7SRichard Smith     template<int, Fn, Fn, Fn> struct T1 { enum { val }; };
1681fff95c7SRichard Smith     template<int, int, int> struct T2 { enum { val }; };
1691fff95c7SRichard Smith     template<int, Fn> struct T3 { enum { val }; };
1701fff95c7SRichard Smith     template<int, typename T> struct T4 : T {};
1711fff95c7SRichard Smith   };
1721fff95c7SRichard Smith }
1731fff95c7SRichard Smith 
1741fff95c7SRichard Smith namespace ElaboratedTypeSpecifiers {
1751fff95c7SRichard Smith   struct S {
1761fff95c7SRichard Smith     int f(int x = T<a, struct S>());
1771fff95c7SRichard Smith     int h(int x = T<a, union __attribute__(()) U>());
1781fff95c7SRichard Smith     int i(int x = T<a, enum E>());
1791fff95c7SRichard Smith     int j(int x = T<a, struct S::template T<0, enum E>>());
1801fff95c7SRichard Smith     template <int, typename> struct T { operator int(); };
1811fff95c7SRichard Smith     static const int a = 0;
1821fff95c7SRichard Smith     enum E {};
1831fff95c7SRichard Smith   };
1841fff95c7SRichard Smith }
1859303357eSRichard Smith 
1869303357eSRichard Smith namespace PR20459 {
1879303357eSRichard Smith   template <typename EncTraits> struct A {
1889303357eSRichard Smith      void foo(int = EncTraits::template TypeEnc<int, int>::val); // ok
1899303357eSRichard Smith   };
1909303357eSRichard Smith }
191