Daniel Dunbar | a572887 | 2009-12-15 20:14:24 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 2 | template<typename T, typename U> |
| 3 | struct X0 { |
| 4 | void f(T x, U y) { |
Douglas Gregor | d7e2705 | 2009-05-20 22:33:37 +0000 | [diff] [blame] | 5 | (void)(x + y); // expected-error{{invalid operands}} |
Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 6 | } |
| 7 | }; |
| 8 | |
| 9 | struct X1 { }; |
| 10 | |
| 11 | template struct X0<int, float>; |
| 12 | template struct X0<int*, int>; |
| 13 | template struct X0<int X1::*, int>; // expected-note{{instantiation of}} |
Douglas Gregor | e7a18c8 | 2009-05-14 23:40:54 +0000 | [diff] [blame] | 14 | |
| 15 | template<typename T> |
| 16 | struct X2 { |
| 17 | void f(T); |
| 18 | |
| 19 | T g(T x, T y) { |
Douglas Gregor | b9f1b8d | 2009-05-15 00:01:03 +0000 | [diff] [blame] | 20 | /* DeclStmt */; |
| 21 | T *xp = &x, &yr = y; // expected-error{{pointer to a reference}} |
Douglas Gregor | e7a18c8 | 2009-05-14 23:40:54 +0000 | [diff] [blame] | 22 | /* NullStmt */; |
| 23 | } |
| 24 | }; |
| 25 | |
| 26 | template struct X2<int>; |
Douglas Gregor | b9f1b8d | 2009-05-15 00:01:03 +0000 | [diff] [blame] | 27 | template struct X2<int&>; // expected-note{{instantiation of}} |
Anders Carlsson | 137fa56 | 2009-05-15 00:15:26 +0000 | [diff] [blame] | 28 | |
| 29 | template<typename T> |
| 30 | struct X3 { |
| 31 | void f(T) { |
| 32 | Label: |
| 33 | T x; |
| 34 | goto Label; |
| 35 | } |
| 36 | }; |
| 37 | |
| 38 | template struct X3<int>; |
Anders Carlsson | 03d7776 | 2009-05-15 00:48:27 +0000 | [diff] [blame] | 39 | |
| 40 | template <typename T> struct X4 { |
| 41 | T f() const { |
| 42 | return; // expected-warning{{non-void function 'f' should return a value}} |
| 43 | } |
| 44 | |
| 45 | T g() const { |
| 46 | return 1; // expected-warning{{void function 'g' should not return a value}} |
| 47 | } |
| 48 | }; |
| 49 | |
Douglas Gregor | f3e7ce4 | 2009-05-18 17:01:57 +0000 | [diff] [blame] | 50 | template struct X4<void>; // expected-note{{in instantiation of}} |
| 51 | template struct X4<int>; // expected-note{{in instantiation of}} |
Douglas Gregor | e2c31ff | 2009-05-15 17:59:04 +0000 | [diff] [blame] | 52 | |
Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 53 | struct Incomplete; // expected-note 2{{forward declaration}} |
Douglas Gregor | e2c31ff | 2009-05-15 17:59:04 +0000 | [diff] [blame] | 54 | |
| 55 | template<typename T> struct X5 { |
| 56 | T f() { } // expected-error{{incomplete result type}} |
| 57 | }; |
| 58 | void test_X5(X5<Incomplete> x5); // okay! |
| 59 | |
| 60 | template struct X5<Incomplete>; // expected-note{{instantiation}} |
Douglas Gregor | d06f6ca | 2009-05-15 18:53:42 +0000 | [diff] [blame] | 61 | |
| 62 | template<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; |
Douglas Gregor | 49f25ec | 2009-05-15 21:18:27 +0000 | [diff] [blame] | 67 | else { |
| 68 | if (t < 0) |
| 69 | return v; // expected-error{{incompatible type}} |
| 70 | } |
| 71 | |
Douglas Gregor | e06274d | 2009-05-20 21:51:01 +0000 | [diff] [blame] | 72 | if (T x = t) { |
| 73 | t = x; |
| 74 | } |
Douglas Gregor | 49f25ec | 2009-05-15 21:18:27 +0000 | [diff] [blame] | 75 | return v; |
Douglas Gregor | d06f6ca | 2009-05-15 18:53:42 +0000 | [diff] [blame] | 76 | } |
| 77 | }; |
| 78 | |
| 79 | struct ConvertibleToInt { |
| 80 | operator int() const; |
| 81 | }; |
| 82 | |
| 83 | template struct X6<ConvertibleToInt, float, char>; |
| 84 | template struct X6<bool, int, int*>; // expected-note{{instantiation}} |
Anders Carlsson | 0712d29 | 2009-05-15 20:26:03 +0000 | [diff] [blame] | 85 | |
| 86 | template <typename T> struct X7 { |
| 87 | void f() { |
| 88 | void *v = this; |
| 89 | } |
| 90 | }; |
| 91 | |
| 92 | template struct X7<int>; |
Douglas Gregor | 4a2e204 | 2009-05-15 21:45:53 +0000 | [diff] [blame] | 93 | |
| 94 | template<typename T> struct While0 { |
| 95 | void f(T t) { |
| 96 | while (t) { |
| 97 | } |
| 98 | |
| 99 | while (T t2 = T()) ; |
| 100 | } |
| 101 | }; |
| 102 | |
| 103 | template struct While0<float>; |
Douglas Gregor | 9f3ca2a | 2009-05-15 21:56:04 +0000 | [diff] [blame] | 104 | |
| 105 | template<typename T> struct Do0 { |
| 106 | void f(T t) { |
| 107 | do { |
| 108 | } while (t); // expected-error{{not contextually}} |
Douglas Gregor | 9f3ca2a | 2009-05-15 21:56:04 +0000 | [diff] [blame] | 109 | } |
| 110 | }; |
| 111 | |
| 112 | struct NotConvertibleToBool { }; |
| 113 | template struct Do0<ConvertibleToInt>; |
| 114 | template struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}} |
Douglas Gregor | 5831c6a | 2009-05-15 22:12:32 +0000 | [diff] [blame] | 115 | |
| 116 | template<typename T> struct For0 { |
| 117 | void f(T f, T l) { |
| 118 | for (; f != l; ++f) { |
Douglas Gregor | 861ce31 | 2009-05-15 22:32:39 +0000 | [diff] [blame] | 119 | if (*f) |
| 120 | continue; |
| 121 | else if (*f == 17) |
| 122 | break; |
Douglas Gregor | 5831c6a | 2009-05-15 22:12:32 +0000 | [diff] [blame] | 123 | } |
| 124 | } |
| 125 | }; |
| 126 | |
| 127 | template struct For0<int*>; |
Anders Carlsson | ffce2df | 2009-05-15 23:10:19 +0000 | [diff] [blame] | 128 | |
| 129 | template<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; |
Anders Carlsson | 4e57992 | 2009-07-10 21:35:09 +0000 | [diff] [blame] | 140 | this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}} |
Anders Carlsson | ffce2df | 2009-05-15 23:10:19 +0000 | [diff] [blame] | 141 | } |
| 142 | }; |
Douglas Gregor | dbb26db | 2009-05-15 23:57:33 +0000 | [diff] [blame] | 143 | |
| 144 | template<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 | |
| 159 | template struct Switch0<int, float>; |
| 160 | |
| 161 | template<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 | |
| 171 | template struct Switch1<int, 1, 2>; |
| 172 | template struct Switch1<int, 2, 2>; // expected-note{{instantiation}} |
Douglas Gregor | 5f1b9e6 | 2009-05-16 00:20:29 +0000 | [diff] [blame] | 173 | |
| 174 | template<typename T> struct IndirectGoto0 { |
| 175 | void f(T x) { |
| 176 | // FIXME: crummy error message below |
| 177 | goto *x; // expected-error{{incompatible}} |
Douglas Gregor | 7665823 | 2009-05-22 23:25:52 +0000 | [diff] [blame] | 178 | |
| 179 | prior: |
| 180 | T prior_label = &&prior; |
| 181 | |
| 182 | T later_label = &&later; |
| 183 | |
| 184 | later: |
| 185 | (void)(1+1); |
Douglas Gregor | 5f1b9e6 | 2009-05-16 00:20:29 +0000 | [diff] [blame] | 186 | } |
| 187 | }; |
| 188 | |
| 189 | template struct IndirectGoto0<void*>; |
| 190 | template struct IndirectGoto0<int>; // expected-note{{instantiation}} |
Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 191 | |
| 192 | template<typename T> struct TryCatch0 { |
| 193 | void f() { |
| 194 | try { |
| 195 | } catch (T t) { // expected-error{{incomplete type}} \ |
| 196 | // expected-error{{abstract class}} |
| 197 | } catch (...) { |
| 198 | } |
| 199 | } |
| 200 | }; |
| 201 | |
| 202 | struct Abstract { |
| 203 | virtual void foo() = 0; // expected-note{{pure virtual}} |
| 204 | }; |
| 205 | |
| 206 | template struct TryCatch0<int>; // okay |
| 207 | template struct TryCatch0<Incomplete*>; // expected-note{{instantiation}} |
| 208 | template struct TryCatch0<Abstract>; // expected-note{{instantiation}} |
Anders Carlsson | 31a0875 | 2009-06-13 02:59:33 +0000 | [diff] [blame] | 209 | |
| 210 | // PR4383 |
| 211 | template<typename T> struct X; |
| 212 | template<typename T> struct Y : public X<T> { |
| 213 | Y& x() { return *this; } |
| 214 | }; |