1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s 2 // RUN: %clang_cc1 -verify=ref,both %s 3 4 /// FIXME: Slight difference in diagnostic output here. 5 6 struct Foo { 7 int a; 8 }; 9 10 constexpr int dead1() { 11 12 Foo *F2 = nullptr; 13 { 14 Foo F{12}; // expected-note {{declared here}} 15 F2 = &F; 16 } // Ends lifetime of F. 17 18 return F2->a; // expected-note {{read of variable whose lifetime has ended}} \ 19 // ref-note {{read of object outside its lifetime is not allowed in a constant expression}} 20 } 21 static_assert(dead1() == 1, ""); // both-error {{not an integral constant expression}} \ 22 // both-note {{in call to}} 23 24 25 struct S { 26 int &&r; // both-note {{reference member declared here}} 27 int t; 28 constexpr S() : r(0), t(r) {} // both-error {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} \ 29 // ref-note {{read of object outside its lifetime is not allowed in a constant expression}} \ 30 // expected-note {{temporary created here}} \ 31 // expected-note {{read of temporary whose lifetime has ended}} 32 }; 33 constexpr int k1 = S().t; // both-error {{must be initialized by a constant expression}} \ 34 // ref-note {{in call to}} \ 35 // expected-note {{in call to}} 36 37 38 namespace MoveFnWorks { 39 template<typename T> constexpr T &&ref(T &&t) { return (T&&)t; } 40 41 struct Buf {}; 42 43 struct A { 44 constexpr A(Buf &buf) : buf(buf) { } 45 Buf &buf; 46 }; 47 48 constexpr bool dtor_calls_dtor() { 49 struct B { 50 A &&d; 51 constexpr B(Buf &buf) : d(ref(A(buf))) {} 52 }; 53 54 Buf buf; 55 { 56 B b(buf); 57 } 58 59 return true; 60 } 61 static_assert(dtor_calls_dtor(), ""); 62 } 63 64 namespace PrimitiveMoveFn { 65 /// This used to crash. 66 void test() { 67 const float y = 100; 68 const float &x = y; 69 } 70 } 71