1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
2template<typename T, typename U>
3struct X0 {
4  void f(T x, U y) {
5    (void)(x + y); // expected-error{{invalid operands}}
6  }
7};
8
9struct X1 { };
10
11template struct X0<int, float>;
12template struct X0<int*, int>;
13template struct X0<int X1::*, int>; // expected-note{{instantiation of}}
14
15template<typename T>
16struct X2 {
17  void f(T);
18
19  T g(T x, T y) {
20    /* DeclStmt */;
21    T *xp = &x, &yr = y; // expected-error{{pointer to a reference}}
22    /* NullStmt */;
23  }
24};
25
26template struct X2<int>;
27template struct X2<int&>; // expected-note{{instantiation of}}
28
29template<typename T>
30struct X3 {
31  void f(T) {
32    Label:
33    T x;
34    goto Label;
35  }
36};
37
38template struct X3<int>;
39
40template <typename T> struct X4 {
41  T f() const {
42    return; // expected-error{{non-void function 'f' should return a value}}
43  }
44
45  T g() const {
46    return 1; // expected-error{{void function 'g' should not return a value}}
47  }
48};
49
50template struct X4<void>; // expected-note{{in instantiation of}}
51template struct X4<int>; // expected-note{{in instantiation of}}
52
53struct Incomplete; // expected-note 2{{forward declaration}}
54
55template<typename T> struct X5 {
56  T f() { } // expected-error{{incomplete result type}}
57};
58void test_X5(X5<Incomplete> x5); // okay!
59
60template struct X5<Incomplete>; // expected-note{{instantiation}}
61
62template<typename T, typename U, typename V> struct X6 {
63  U f(T t, U u, V v) {
64    // IfStmt
65    if (t > 0)
66      return u;
67    else {
68      if (t < 0)
69        return v; // expected-error{{cannot initialize return object of type}}
70    }
71
72    if (T x = t) {
73      t = x;
74    }
75    return v; // expected-error{{cannot initialize return object of type}}
76  }
77};
78
79struct ConvertibleToInt {
80  operator int() const;
81};
82
83template struct X6<ConvertibleToInt, float, char>;
84template struct X6<bool, int, int*>; // expected-note{{instantiation}}
85
86template <typename T> struct X7 {
87  void f() {
88    void *v = this;
89  }
90};
91
92template struct X7<int>;
93
94template<typename T> struct While0 {
95  void f(T t) {
96    while (t) {
97    }
98
99    while (T t2 = T()) ;
100  }
101};
102
103template struct While0<float>;
104
105template<typename T> struct Do0 {
106  void f(T t) {
107    do {
108    } while (t); // expected-error{{not contextually}}
109  }
110};
111
112struct NotConvertibleToBool { };
113template struct Do0<ConvertibleToInt>;
114template struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}}
115
116template<typename T> struct For0 {
117  void f(T f, T l) {
118    for (; f != l; ++f) {
119      if (*f)
120        continue;
121      else if (*f == 17)
122        break;
123    }
124  }
125};
126
127template struct For0<int*>;
128
129template<typename T> struct Member0 {
130  void f(T t) {
131    t;
132    t.f;
133    t->f;
134
135    T* tp;
136    tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}}
137    tp->f;
138
139    this->f;
140    this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}}
141  }
142};
143
144template<typename T, typename U> struct Switch0 {
145  U f(T value, U v0, U v1, U v2) {
146    switch (value) {
147    case 0: return v0;
148
149    case 1: return v1;
150
151    case 2: // fall through
152
153    default:
154      return  v2;
155    }
156  }
157};
158
159template struct Switch0<int, float>;
160
161template<typename T, int I1, int I2> struct Switch1 {
162  T f(T x, T y, T z) {
163    switch (x) {
164    case I1: return y; // expected-note{{previous}}
165    case I2: return z; // expected-error{{duplicate}}
166    default: return x;
167    }
168  }
169};
170
171template struct Switch1<int, 1, 2>;
172template struct Switch1<int, 2, 2>; // expected-note{{instantiation}}
173
174template<typename T> struct IndirectGoto0 {
175  void f(T x) {
176    // FIXME: crummy error message below
177    goto *x; // expected-error{{incompatible}}
178
179  prior:
180    T prior_label;
181    prior_label = &&prior; // expected-error{{assigning to 'int'}}
182
183    T later_label;
184    later_label = &&later; // expected-error{{assigning to 'int'}}
185
186  later:
187    (void)(1+1);
188  }
189};
190
191template struct IndirectGoto0<void*>;
192template struct IndirectGoto0<int>; // expected-note{{instantiation}}
193
194template<typename T> struct TryCatch0 {
195  void f() {
196    try {
197    } catch (T t) { // expected-error{{incomplete type}} \
198                    // expected-error{{abstract class}}
199    } catch (...) {
200    }
201  }
202};
203
204struct Abstract {
205  virtual void foo() = 0; // expected-note{{pure virtual}}
206};
207
208template struct TryCatch0<int>; // okay
209template struct TryCatch0<Incomplete*>; // expected-note{{instantiation}}
210template struct TryCatch0<Abstract>; // expected-note{{instantiation}}
211
212// PR4383
213template<typename T> struct X;
214template<typename T> struct Y : public X<T> {
215  Y& x() { return *this; }
216};
217
218// Make sure our assertions don't get too uppity.
219namespace test0 {
220  template <class T> class A { void foo(T array[10]); };
221  template class A<int>;
222}
223
224namespace PR7016 {
225  template<typename T> void f() { T x = x; }
226  template void f<int>();
227}
228
229namespace PR9880 {
230  struct lua_State;
231  struct no_tag { char a; };			// (A)
232  struct yes_tag { long a; long b; };	// (A)
233
234  template <typename T>
235  struct HasIndexMetamethod {
236    template <typename U>
237    static no_tag check(...);
238    template <typename U>
239    static yes_tag check(char[sizeof(&U::luaIndex)]);
240    enum { value = sizeof(check<T>(0)) == sizeof(yes_tag) };
241  };
242
243  class SomeClass {
244  public:
245    int luaIndex(lua_State* L);
246  };
247
248  int i = HasIndexMetamethod<SomeClass>::value;
249}
250