[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