[clang] [clang][bytecode] Start lifetime when activating pointers (PR #192589)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 16 20:50:05 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/192589
This can be used to revive union members.
>From 52c56819ab44e7a8aaa2ab88653f608e91bd6d12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 17 Apr 2026 03:24:30 +0200
Subject: [PATCH] asdf
---
clang/lib/AST/ByteCode/Interp.cpp | 2 +-
clang/lib/AST/ByteCode/Pointer.cpp | 1 +
clang/test/AST/ByteCode/unions.cpp | 29 +++++++++++++++++++++++++++++
3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 5bc1067518558..56d7fc5510aa1 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -880,7 +880,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
return false;
return CheckDummy(S, OpPC, Ptr.block(), AK_Assign);
}
- if (!CheckLifetime(S, OpPC, Ptr, AK_Assign))
+ if (!WillBeActivated && !CheckLifetime(S, OpPC, Ptr, AK_Assign))
return false;
if (!CheckRange(S, OpPC, Ptr, AK_Assign))
return false;
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index a0a1c64bfd975..bbb8c8112a81b 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -644,6 +644,7 @@ void Pointer::activate() const {
std::function<void(Pointer &)> activate;
activate = [&activate](Pointer &P) -> void {
P.getInlineDesc()->IsActive = true;
+ P.startLifetime();
if (const Record *R = P.getRecord(); R && !R->isUnion()) {
for (const Record::Field &F : R->fields()) {
Pointer FieldPtr = P.atField(F.Offset);
diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp
index 8c6f52c837374..399c4c891be00 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -1042,4 +1042,33 @@ namespace NoTrivialCtor {
}
static_assert(foo() == 10);
}
+
+namespace Revive {
+ struct S { int p; };
+ struct A { S s;};
+ union U { A a; };
+
+ constexpr int g() {
+ U u;
+ u.a.s.p = 3;
+ u.a.~A();
+ u.a.s.p = 4; // Start lifetime of 'a' again.
+ int r = u.a.s.p;
+ u.a.~A();
+ return r;
+ }
+ static_assert(g() == 4);
+
+ constexpr int h() {
+ A a; // both-note {{declared here}}
+ a.s.p = 10;
+
+ a.s.~S();
+ a.s.p = 20; // both-note {{assignment to object outside its lifetime}}
+ int r = a.s.p;
+ return r;
+ }
+ static_assert(h() == 20); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+}
#endif
More information about the cfe-commits
mailing list