diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 1ef13f558b753..fb50d1c6c5833 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1,11 +1,11 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify %s -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify %s -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple i686 -verify %s -// RUN: %clang_cc1 -verify=ref %s -// RUN: %clang_cc1 -verify=ref -std=c++14 %s -// RUN: %clang_cc1 -verify=ref -std=c++20 %s -// RUN: %clang_cc1 -verify=ref -triple i686 %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify=expected,both %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,both %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple i686 -verify=expected,both %s +// RUN: %clang_cc1 -verify=ref,both %s +// RUN: %clang_cc1 -verify=ref,both -std=c++14 %s +// RUN: %clang_cc1 -verify=ref,both -std=c++20 %s +// RUN: %clang_cc1 -verify=ref,both -triple i686 %s /// Used to crash. struct Empty {}; @@ -90,9 +90,8 @@ struct Ints2 { int a = 10; int b; }; -constexpr Ints2 ints22; // expected-error {{without a user-provided default constructor}} \ - // expected-error {{must be initialized by a constant expression}} \ - // ref-error {{without a user-provided default constructor}} +constexpr Ints2 ints22; // both-error {{without a user-provided default constructor}} \ + // expected-error {{must be initialized by a constant expression}} constexpr Ints2 I2 = Ints2{12, 25}; static_assert(I2.a == 12, ""); @@ -164,17 +163,13 @@ constexpr C RVOAndParams(int a) { } constexpr C RVOAndParamsResult2 = RVOAndParams(12); -class Bar { // expected-note {{definition of 'Bar' is not complete}} \ - // ref-note {{definition of 'Bar' is not complete}} +class Bar { // both-note {{definition of 'Bar' is not complete}} public: constexpr Bar(){} - constexpr Bar b; // expected-error {{cannot be constexpr}} \ - // expected-error {{has incomplete type 'const Bar'}} \ - // ref-error {{cannot be constexpr}} \ - // ref-error {{has incomplete type 'const Bar'}} + constexpr Bar b; // both-error {{cannot be constexpr}} \ + // both-error {{has incomplete type 'const Bar'}} }; -constexpr Bar B; // expected-error {{must be initialized by a constant expression}} \ - // ref-error {{must be initialized by a constant expression}} +constexpr Bar B; // both-error {{must be initialized by a constant expression}} constexpr Bar *pb = nullptr; constexpr int locals() { @@ -198,17 +193,13 @@ namespace thisPointer { constexpr int get12() { return 12; } }; - constexpr int foo() { // ref-error {{never produces a constant expression}} \ - // expected-error {{never produces a constant expression}} + constexpr int foo() { // both-error {{never produces a constant expression}} S *s = nullptr; - return s->get12(); // ref-note 2{{member call on dereferenced null pointer}} \ - // expected-note 2{{member call on dereferenced null pointer}} + return s->get12(); // both-note 2{{member call on dereferenced null pointer}} } - static_assert(foo() == 12, ""); // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'foo()'}} \ - // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to 'foo()'}} + static_assert(foo() == 12, ""); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'foo()'}} }; struct FourBoolPairs { @@ -244,20 +235,16 @@ constexpr A a{}; static_assert(a.i == 100, ""); constexpr A a2{12}; static_assert(a2.i == 12, ""); -static_assert(a2.i == 200, ""); // ref-error {{static assertion failed}} \ - // ref-note {{evaluates to '12 == 200'}} \ - // expected-error {{static assertion failed}} \ - // expected-note {{evaluates to '12 == 200'}} +static_assert(a2.i == 200, ""); // both-error {{static assertion failed}} \ + // both-note {{evaluates to '12 == 200'}} struct S { int a = 0; constexpr int get5() const { return 5; } constexpr void fo() const { - this; // expected-warning {{expression result unused}} \ - // ref-warning {{expression result unused}} - this->a; // expected-warning {{expression result unused}} \ - // ref-warning {{expression result unused}} + this; // both-warning {{expression result unused}} + this->a; // both-warning {{expression result unused}} get5(); getInts(); } @@ -342,12 +329,9 @@ namespace InitializerTemporaries { // Invalid destructor. struct S { constexpr S() {} - constexpr ~S() noexcept(false) { throw 12; } // expected-error {{cannot use 'throw'}} \ - // expected-error {{never produces a constant expression}} \ - // expected-note 2{{subexpression not valid}} \ - // ref-error {{cannot use 'throw'}} \ - // ref-error {{never produces a constant expression}} \ - // ref-note 2{{subexpression not valid}} + constexpr ~S() noexcept(false) { throw 12; } // both-error {{cannot use 'throw'}} \ + // both-error {{never produces a constant expression}} \ + // both-note 2{{subexpression not valid}} }; constexpr int f() { @@ -355,10 +339,8 @@ namespace InitializerTemporaries { /// FIXME: Wrong source location below. return 12; // expected-note {{in call to '&S{}->~S()'}} } - static_assert(f() == 12); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to 'f()'}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'f()'}} + static_assert(f() == 12); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'f()'}} #endif @@ -423,7 +405,8 @@ namespace MI { namespace DeriveFailures { #if __cplusplus < 202002L - struct Base { // ref-note 2{{declared here}} expected-note {{declared here}} + struct Base { // both-note {{declared here}} \ + // ref-note {{declared here}} int Val; }; @@ -431,35 +414,29 @@ namespace DeriveFailures { int OtherVal; constexpr Derived(int i) : OtherVal(i) {} // ref-error {{never produces a constant expression}} \ - // ref-note 2{{non-constexpr constructor 'Base' cannot be used in a constant expression}} \ - // expected-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} + // both-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} \ + // ref-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} }; - constexpr Derived D(12); // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{in call to 'Derived(12)'}} \ - // ref-note {{declared here}} \ - // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{in call to 'Derived(12)'}} + constexpr Derived D(12); // both-error {{must be initialized by a constant expression}} \ + // both-note {{in call to 'Derived(12)'}} \ + // ref-note {{declared here}} - static_assert(D.Val == 0, ""); // ref-error {{not an integral constant expression}} \ + static_assert(D.Val == 0, ""); // both-error {{not an integral constant expression}} \ // ref-note {{initializer of 'D' is not a constant expression}} \ - // expected-error {{not an integral constant expression}} \ // expected-note {{read of uninitialized object}} #endif struct AnotherBase { int Val; - constexpr AnotherBase(int i) : Val(12 / i) {} //ref-note {{division by zero}} \ - //expected-note {{division by zero}} + constexpr AnotherBase(int i) : Val(12 / i) {} // both-note {{division by zero}} }; struct AnotherDerived : AnotherBase { constexpr AnotherDerived(int i) : AnotherBase(i) {} }; - constexpr AnotherBase Derp(0); // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{in call to 'AnotherBase(0)'}} \ - // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{in call to 'AnotherBase(0)'}} + constexpr AnotherBase Derp(0); // both-error {{must be initialized by a constant expression}} \ + // both-note {{in call to 'AnotherBase(0)'}} struct YetAnotherBase { int Val; @@ -467,17 +444,14 @@ namespace DeriveFailures { }; struct YetAnotherDerived : YetAnotherBase { - using YetAnotherBase::YetAnotherBase; // ref-note {{declared here}} \ - // expected-note {{declared here}} + using YetAnotherBase::YetAnotherBase; // both-note {{declared here}} int OtherVal; constexpr bool doit() const { return Val == OtherVal; } }; - constexpr YetAnotherDerived Oops(0); // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{constructor inherited from base class 'YetAnotherBase' cannot be used in a constant expression}} \ - // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{constructor inherited from base class 'YetAnotherBase' cannot be used in a constant expression}} + constexpr YetAnotherDerived Oops(0); // both-error {{must be initialized by a constant expression}} \ + // both-note {{constructor inherited from base class 'YetAnotherBase' cannot be used in a constant expression}} }; namespace EmptyCtor { @@ -543,18 +517,10 @@ namespace PointerArith { constexpr B *b1 = &b + 1; constexpr B *b2 = &b + 0; -#if 0 - constexpr A *a2 = &b + 1; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{cannot access base class of pointer past the end of object}} \ - // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{cannot access base class of pointer past the end of object}} - -#endif - constexpr const int *pn = &(&b + 1)->n; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{cannot access field of pointer past the end of object}} \ - // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{cannot access field of pointer past the end of object}} - + constexpr A *a2 = &b + 1; // both-error {{must be initialized by a constant expression}} \ + // both-note {{cannot access base class of pointer past the end of object}} + constexpr const int *pn = &(&b + 1)->n; // both-error {{must be initialized by a constant expression}} \ + // both-note {{cannot access field of pointer past the end of object}} } #if __cplusplus >= 202002L @@ -632,12 +598,9 @@ namespace Destructors { struct S { constexpr S() {} - constexpr ~S() { // expected-error {{never produces a constant expression}} \ - // ref-error {{never produces a constant expression}} - int i = 1 / 0; // expected-warning {{division by zero}} \ - // expected-note 2{{division by zero}} \ - // ref-warning {{division by zero}} \ - // ref-note 2{{division by zero}} + constexpr ~S() { // both-error {{never produces a constant expression}} + int i = 1 / 0; // both-warning {{division by zero}} \ + // both-note 2{{division by zero}} } }; constexpr int testS() { @@ -645,10 +608,8 @@ namespace Destructors { return 1; // expected-note {{in call to '&S{}->~S()'}} // FIXME: ^ Wrong line } - static_assert(testS() == 1); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to 'testS()'}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'testS()'}} + static_assert(testS() == 1); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'testS()'}} } namespace BaseToDerived { @@ -657,10 +618,8 @@ namespace A { struct B : A { int n; }; struct C : B {}; C c = {}; - constexpr C *pb = (C*)((A*)&c + 1); // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{cannot access derived class of pointer past the end of object}} \ - // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{cannot access derived class of pointer past the end of object}} + constexpr C *pb = (C*)((A*)&c + 1); // both-error {{must be initialized by a constant expression}} \ + // both-note {{cannot access derived class of pointer past the end of object}} } namespace B { struct A {}; @@ -894,10 +853,8 @@ namespace VirtualFromBase { // Virtual f(), not OK. constexpr X> xxs2; constexpr X *q = const_cast>*>(&xxs2); - static_assert(q->f() == sizeof(X), ""); // ref-error {{not an integral constant expression}} \ - // ref-note {{cannot evaluate call to virtual function}} \ - // expected-error {{not an integral constant expression}} \ - // expected-note {{cannot evaluate call to virtual function}} + static_assert(q->f() == sizeof(X), ""); // both-error {{not an integral constant expression}} \ + // both-note {{cannot evaluate call to virtual function}} } #endif @@ -1070,14 +1027,10 @@ namespace ParenInit { /// Not constexpr! O o1(0); - constinit O o2(0); // ref-error {{variable does not have a constant initializer}} \ - // ref-note {{required by 'constinit' specifier}} \ - // ref-note {{reference to temporary is not a constant expression}} \ - // ref-note {{temporary created here}} \ - // expected-error {{variable does not have a constant initializer}} \ - // expected-note {{required by 'constinit' specifier}} \ - // expected-note {{reference to temporary is not a constant expression}} \ - // expected-note {{temporary created here}} + constinit O o2(0); // both-error {{variable does not have a constant initializer}} \ + // both-note {{required by 'constinit' specifier}} \ + // both-note {{reference to temporary is not a constant expression}} \ + // both-note {{temporary created here}} } #endif @@ -1109,32 +1062,24 @@ namespace AccessOnNullptr { int a; }; - constexpr int a() { // expected-error {{never produces a constant expression}} \ - // ref-error {{never produces a constant expression}} + constexpr int a() { // both-error {{never produces a constant expression}} F *f = nullptr; - f->a = 0; // expected-note 2{{cannot access field of null pointer}} \ - // ref-note 2{{cannot access field of null pointer}} + f->a = 0; // both-note 2{{cannot access field of null pointer}} return f->a; } - static_assert(a() == 0, ""); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to 'a()'}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'a()'}} + static_assert(a() == 0, ""); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'a()'}} - constexpr int a2() { // expected-error {{never produces a constant expression}} \ - // ref-error {{never produces a constant expression}} + constexpr int a2() { // both-error {{never produces a constant expression}} F *f = nullptr; - const int *a = &(f->a); // expected-note 2{{cannot access field of null pointer}} \ - // ref-note 2{{cannot access field of null pointer}} + const int *a = &(f->a); // both-note 2{{cannot access field of null pointer}} return f->a; } - static_assert(a2() == 0, ""); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to 'a2()'}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'a2()'}} + static_assert(a2() == 0, ""); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'a2()'}} } namespace IndirectFieldInit {