|
5 | 5 | // RUN: %clang_cc1 -verify=ref -std=c++14 %s
|
6 | 6 | // RUN: %clang_cc1 -verify=ref -triple i686 %s
|
7 | 7 |
|
8 |
| -// expected-no-diagnostics |
9 |
| - |
10 | 8 | struct BoolPair {
|
11 | 9 | bool first;
|
12 | 10 | bool second;
|
@@ -181,3 +179,116 @@ static_assert(LT2.v[0].first == false, "");
|
181 | 179 | static_assert(LT2.v[0].second == false, "");
|
182 | 180 | static_assert(LT2.v[2].first == true, "");
|
183 | 181 | static_assert(LT2.v[2].second == false, "");
|
| 182 | + |
| 183 | +class Base { |
| 184 | +public: |
| 185 | + int i; |
| 186 | + constexpr Base() : i(10) {} |
| 187 | + constexpr Base(int i) : i(i) {} |
| 188 | +}; |
| 189 | + |
| 190 | +class A : public Base { |
| 191 | +public: |
| 192 | + constexpr A() : Base(100) {} |
| 193 | + constexpr A(int a) : Base(a) {} |
| 194 | +}; |
| 195 | +constexpr A a{}; |
| 196 | +static_assert(a.i == 100, ""); |
| 197 | +constexpr A a2{12}; |
| 198 | +static_assert(a2.i == 12, ""); |
| 199 | +static_assert(a2.i == 200, ""); // ref-error {{static assertion failed}} \ |
| 200 | + // ref-note {{evaluates to '12 == 200'}} \ |
| 201 | + // expected-error {{static assertion failed}} \ |
| 202 | + // expected-note {{evaluates to '12 == 200'}} |
| 203 | + |
| 204 | +namespace MI { |
| 205 | + class A { |
| 206 | + public: |
| 207 | + int a; |
| 208 | + constexpr A(int a) : a(a) {} |
| 209 | + }; |
| 210 | + |
| 211 | + class B { |
| 212 | + public: |
| 213 | + int b; |
| 214 | + constexpr B(int b) : b(b) {} |
| 215 | + }; |
| 216 | + |
| 217 | + class C : public A, public B { |
| 218 | + public: |
| 219 | + constexpr C() : A(10), B(20) {} |
| 220 | + }; |
| 221 | + constexpr C c = {}; |
| 222 | + static_assert(c.a == 10, ""); |
| 223 | + static_assert(c.b == 20, ""); |
| 224 | + |
| 225 | + |
| 226 | + class D : private A, private B { |
| 227 | + public: |
| 228 | + constexpr D() : A(20), B(30) {} |
| 229 | + constexpr int getA() const { return a; } |
| 230 | + constexpr int getB() const { return b; } |
| 231 | + }; |
| 232 | + constexpr D d = {}; |
| 233 | + static_assert(d.getA() == 20, ""); |
| 234 | + static_assert(d.getB() == 30, ""); |
| 235 | +}; |
| 236 | + |
| 237 | +namespace DeriveFailures { |
| 238 | + struct Base { // ref-note 2{{declared here}} |
| 239 | + int Val; |
| 240 | + }; |
| 241 | + |
| 242 | + struct Derived : Base { |
| 243 | + int OtherVal; |
| 244 | + |
| 245 | + constexpr Derived(int i) : OtherVal(i) {} // ref-error {{never produces a constant expression}} \ |
| 246 | + // ref-note 2{{non-constexpr constructor 'Base' cannot be used in a constant expression}} |
| 247 | + }; |
| 248 | + |
| 249 | + // FIXME: This is currently not being diagnosed with the new constant interpreter. |
| 250 | + constexpr Derived D(12); // ref-error {{must be initialized by a constant expression}} \ |
| 251 | + // ref-note {{in call to 'Derived(12)'}} \ |
| 252 | + // ref-note {{declared here}} \ |
| 253 | + // expected-error {{must be initialized by a constant expression}} |
| 254 | + static_assert(D.Val == 0, ""); // ref-error {{not an integral constant expression}} \ |
| 255 | + // ref-note {{initializer of 'D' is not a constant expression}} |
| 256 | + |
| 257 | +#if 0 |
| 258 | + // FIXME: This test is currently disabled because the failing constructor call |
| 259 | + // causes us to run into an assertion later on in the new interpreter. |
| 260 | + // Once that is fixed, we fail successfully but the diagnostic uses the |
| 261 | + // wrong value. |
| 262 | + struct AnotherBase { |
| 263 | + int Val; |
| 264 | + constexpr AnotherBase(int i) : Val(12 / i) {} //ref-note {{division by zero}} \ |
| 265 | + //expected-note {{division by zero}} |
| 266 | + }; |
| 267 | + |
| 268 | + struct AnotherDerived : AnotherBase { |
| 269 | + constexpr AnotherDerived(int i) : AnotherBase(i) {} |
| 270 | + }; |
| 271 | + constexpr AnotherBase Derp(0); // ref-error {{must be initialized by a constant expression}} \ |
| 272 | + // ref-note {{in call to 'AnotherBase(0)'}} \ |
| 273 | + // expected-error {{must be initialized by a constant expression}} \ |
| 274 | + // expected-note {{in call to 'AnotherBase(}} |
| 275 | + // FIXME Previous note uses the wrong value |
| 276 | +#endif |
| 277 | + |
| 278 | + struct YetAnotherBase { |
| 279 | + int Val; |
| 280 | + constexpr YetAnotherBase(int i) : Val(i) {} |
| 281 | + }; |
| 282 | + |
| 283 | + struct YetAnotherDerived : YetAnotherBase { |
| 284 | + using YetAnotherBase::YetAnotherBase; //ref-note {{declared here}} |
| 285 | + int OtherVal; |
| 286 | + |
| 287 | + constexpr bool doit() const { return Val == OtherVal; } |
| 288 | + }; |
| 289 | + |
| 290 | + constexpr YetAnotherDerived Oops(0); // ref-error {{must be initialized by a constant expression}} \ |
| 291 | + // ref-note {{constructor inherited from base class 'YetAnotherBase' cannot be used in a constant expression}} \ |
| 292 | + // expected-error {{must be initialized by a constant expression}} |
| 293 | + // FIXME: Missing reason for rejection. |
| 294 | +}; |
0 commit comments