Richard Trieu | 406e65c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -Wno-uninitialized -std=c++11 -verify %s |
Richard Smith | 1fff95c | 2013-09-12 23:28:08 +0000 | [diff] [blame] | 2 | |
| 3 | template<int> struct c { c(int) = delete; typedef void val; operator int() const; }; |
| 4 | |
| 5 | int val; |
| 6 | int foobar; |
| 7 | struct S { |
| 8 | int k1 = a < b < c, d > ::val, e1; |
| 9 | int k2 = a < b, c < d > ::val, e2; |
| 10 | int k3 = b < a < c, d > ::val, e3; |
| 11 | int k4 = b < c, x, y = d > ::val, e4; |
| 12 | int k5 = T1 < b, &S::operator=(int); // expected-error {{extra qualification}} |
| 13 | int k6 = T2 < b, &S::operator= >::val; |
| 14 | int k7 = T1 < b, &S::operator>(int); // expected-error {{extra qualification}} |
| 15 | int k8 = T2 < b, &S::operator> >::val; |
| 16 | int k9 = T3 < a < b, c >> (d), e5 = 1 > (e4); |
| 17 | int k10 = 0 < T3 < a < b, c >> (d |
| 18 | ) // expected-error {{expected ';' at end of declaration}} |
| 19 | , a > (e4); |
| 20 | int k11 = 0 < 1, c<3>::*ptr; |
| 21 | int k12 = e < 0, int a<b<c>::* >(), e11; |
| 22 | |
| 23 | void f1( |
| 24 | int k1 = a < b < c, d > ::val, |
| 25 | int k2 = b < a < c, d > ::val, |
| 26 | int k3 = b < c, int x = 0 > ::val, |
| 27 | int k4 = a < b, T3 < int > >(), // expected-error {{must be an expression}} |
| 28 | int k5 = a < b, c < d > ::val, |
| 29 | int k6 = a < b, c < d > (n) // expected-error {{undeclared identifier 'n'}} |
| 30 | ); |
| 31 | |
| 32 | void f2a( |
| 33 | // T3<int> here is a parameter type, so must be declared before it is used. |
| 34 | int k1 = c < b, T3 < int > x = 0 // expected-error {{unexpected end of default argument expression}} |
| 35 | ); |
| 36 | |
| 37 | template<typename, int=0> struct T3 { T3(int); operator int(); }; |
| 38 | |
| 39 | void f2b( |
| 40 | int k1 = c < b, T3 < int > x = 0 // ok |
| 41 | ); |
| 42 | |
| 43 | // This is a one-parameter function. Ensure we don't typo-correct it to |
| 44 | // int = a < b, c < foobar > () |
| 45 | // ... which would be a function with two parameters. |
| 46 | int f3(int = a < b, c < goobar > ()); |
| 47 | static constexpr int (S::*f3_test)(int) = &S::f3; |
| 48 | |
| 49 | void f4( |
| 50 | int k1 = a<1,2>::val, |
| 51 | int missing_default // expected-error {{missing default argument on parameter}} |
| 52 | ); |
| 53 | |
| 54 | void f5( |
| 55 | int k1 = b < c, |
| 56 | int missing_default // expected-error {{missing default argument on parameter}} |
| 57 | ); |
| 58 | |
| 59 | void f6( |
| 60 | int k = b < c, |
| 61 | unsigned int (missing_default) // expected-error {{missing default argument on parameter}} |
| 62 | ); |
| 63 | |
| 64 | template<int, int=0> struct a { static const int val = 0; operator int(); }; // expected-note {{here}} |
| 65 | static const int b = 0, c = 1, d = 2, goobar = 3; |
| 66 | template<int, typename> struct e { operator int(); }; |
| 67 | |
| 68 | int mp1 = 0 < 1, |
| 69 | a<b<c,b<c>::*mp2, |
| 70 | mp3 = 0 > a<b<c>::val, |
| 71 | a<b<c,b<c>::*mp4 = 0, |
| 72 | a<b<c,b<c>::*mp5 {0}, |
| 73 | a<b<c,b<c>::*mp6; |
| 74 | |
| 75 | int np1 = e<0, int a<b<c,b<c>::*>(); |
| 76 | |
| 77 | static const int T1 = 4; |
| 78 | template<int, int &(S::*)(int)> struct T2 { static const int val = 0; }; |
| 79 | }; |
| 80 | |
| 81 | namespace NoAnnotationTokens { |
| 82 | template<bool> struct Bool { Bool(int); }; |
| 83 | static const bool in_class = false; |
| 84 | |
| 85 | struct Test { |
| 86 | // Check we don't keep around a Bool<false> annotation token here. |
| 87 | int f(Bool<true> = X<Y, Bool<in_class> >(0)); |
| 88 | |
| 89 | // But it's OK if we do here. |
| 90 | int g(Bool<true> = Z<Y, Bool<in_class> = Bool<false>(0)); |
| 91 | |
| 92 | static const bool in_class = true; |
| 93 | template<int, typename U> using X = U; |
| 94 | static const int Y = 0, Z = 0; |
| 95 | }; |
| 96 | } |
| 97 | |
| 98 | namespace ImplicitInstantiation { |
| 99 | template<typename T> struct HasError { typename T::error error; }; // expected-error {{has no members}} |
| 100 | |
| 101 | struct S { |
| 102 | // This triggers the instantiation of the outer HasError<int> during |
| 103 | // disambiguation, even though it uses the inner HasError<int>. |
| 104 | void f(int a = X<Y, HasError<int>::Z >()); // expected-note {{in instantiation of}} |
| 105 | |
| 106 | template<typename, typename> struct X { operator int(); }; |
| 107 | typedef int Y; |
| 108 | template<typename> struct HasError { typedef int Z; }; |
| 109 | }; |
| 110 | |
| 111 | HasError<int> hei; |
| 112 | } |
| 113 | |
| 114 | namespace CWG325 { |
| 115 | template <int A, typename B> struct T { static int i; operator int(); }; |
| 116 | class C { |
| 117 | int Foo (int i = T<1, int>::i); |
| 118 | }; |
| 119 | |
| 120 | class D { |
| 121 | int Foo (int i = T<1, int>::i); |
| 122 | template <int A, typename B> struct T {static int i;}; |
| 123 | }; |
| 124 | |
| 125 | const int a = 0; |
| 126 | typedef int b; |
| 127 | T<a,b> c; |
| 128 | struct E { |
| 129 | int n = T<a,b>(c); |
| 130 | }; |
| 131 | } |
| 132 | |
| 133 | namespace Operators { |
| 134 | struct Y {}; |
| 135 | constexpr int operator,(const Y&, const Y&) { return 8; } |
| 136 | constexpr int operator>(const Y&, const Y&) { return 8; } |
| 137 | constexpr int operator<(const Y&, const Y&) { return 8; } |
| 138 | constexpr int operator>>(const Y&, const Y&) { return 8; } |
| 139 | |
| 140 | struct X { |
| 141 | typedef int (*Fn)(const Y&, const Y&); |
| 142 | |
| 143 | Fn a = operator,, b = operator<, c = operator>; |
| 144 | void f(Fn a = operator,, Fn b = operator<, Fn c = operator>); |
| 145 | |
| 146 | int k1 = T1<0, operator<, operator>, operator<>::val, l1; |
| 147 | int k2 = T1<0, operator>, operator,, operator,>::val, l2; |
| 148 | int k3 = T2<0, operator,(Y{}, Y{}), operator<(Y{}, Y{})>::val, l3; |
| 149 | int k4 = T2<0, operator>(Y{}, Y{}), operator,(Y{}, Y{})>::val, l4; |
| 150 | int k5 = T3<0, operator>>>::val, l5; |
| 151 | int k6 = T4<0, T3<0, operator>>>>::val, l6; |
| 152 | |
| 153 | template<int, Fn, Fn, Fn> struct T1 { enum { val }; }; |
| 154 | template<int, int, int> struct T2 { enum { val }; }; |
| 155 | template<int, Fn> struct T3 { enum { val }; }; |
| 156 | template<int, typename T> struct T4 : T {}; |
| 157 | }; |
| 158 | } |
| 159 | |
| 160 | namespace ElaboratedTypeSpecifiers { |
| 161 | struct S { |
| 162 | int f(int x = T<a, struct S>()); |
| 163 | int g(int x = T<a, class __declspec() C>()); |
| 164 | int h(int x = T<a, union __attribute__(()) U>()); |
| 165 | int i(int x = T<a, enum E>()); |
| 166 | int j(int x = T<a, struct S::template T<0, enum E>>()); |
| 167 | template <int, typename> struct T { operator int(); }; |
| 168 | static const int a = 0; |
| 169 | enum E {}; |
| 170 | }; |
| 171 | } |
Richard Smith | 9303357 | 2014-07-27 05:38:12 +0000 | [diff] [blame^] | 172 | |
| 173 | namespace PR20459 { |
| 174 | template <typename EncTraits> struct A { |
| 175 | void foo(int = EncTraits::template TypeEnc<int, int>::val); // ok |
| 176 | }; |
| 177 | } |