[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / AST / ByteCode / lifetimes.cpp
blob9a99485c4a40bffa90c45e2119ed2e8d2251cee5
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2 // RUN: %clang_cc1 -verify=ref,both %s
4 /// FIXME: Slight difference in diagnostic output here.
6 struct Foo {
7 int a;
8 };
10 constexpr int dead1() { // expected-error {{never produces a constant expression}}
12 Foo *F2 = nullptr;
14 Foo F{12}; // expected-note 2{{declared here}}
15 F2 = &F;
16 } // Ends lifetime of F.
18 return F2->a; // expected-note 2{{read of variable whose lifetime has ended}} \
19 // ref-note {{read of object outside its lifetime is not allowed in a constant expression}}
21 static_assert(dead1() == 1, ""); // both-error {{not an integral constant expression}} \
22 // both-note {{in call to}}
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}}
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}}
38 namespace MoveFnWorks {
39 template<typename T> constexpr T &&ref(T &&t) { return (T&&)t; }
41 struct Buf {};
43 struct A {
44 constexpr A(Buf &buf) : buf(buf) { }
45 Buf &buf;
48 constexpr bool dtor_calls_dtor() {
49 struct B {
50 A &&d;
51 constexpr B(Buf &buf) : d(ref(A(buf))) {}
54 Buf buf;
56 B b(buf);
59 return true;
61 static_assert(dtor_calls_dtor(), "");
64 namespace PrimitiveMoveFn {
65 /// This used to crash.
66 void test() {
67 const float y = 100;
68 const float &x = y;