Author: nataliakokoromyti
Date: 2026-01-02T16:49:44+01:00
New Revision: 7976ac990000a58a7474269a3ca95e16aed8c35b

URL: 
https://github.com/llvm/llvm-project/commit/7976ac990000a58a7474269a3ca95e16aed8c35b
DIFF: 
https://github.com/llvm/llvm-project/commit/7976ac990000a58a7474269a3ca95e16aed8c35b.diff

LOG: [clang][bytecode] Check if block is initialized before invoking destructor 
(#174082)

Fixes #173950. 

The bytecode interpreter was crashing when evaluating typeid() on
references to dynamically allocated objects. For example, this would
cause an assertion failure:

static A &a = *new A;
const std::type_info &a_ti = typeid(a);

The problem was that when initialization failed, the code tried to call
invokeDtor() on blocks that were never marked as initialized. This
caused the assertion "IsInitialized" to fail. With this fix, we first
check if the block is actually initialized before trying to invoke its
destructor.

The test case I added reproduces the original crash and with the fix, it
now passes.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/test/AST/ByteCode/typeid.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 67980676dcd30..4518c587ceca7 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4803,7 +4803,8 @@ VarCreationState Compiler<Emitter>::visitDecl(const 
VarDecl *VD,
       auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
 
       GD.InitState = GlobalInitState::InitializerFailed;
-      GlobalBlock->invokeDtor();
+      if (GlobalBlock->isInitialized())
+        GlobalBlock->invokeDtor();
     }
   }
 
@@ -4864,7 +4865,8 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl 
*VD, const Expr *Init,
       auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
 
       GD.InitState = GlobalInitState::InitializerFailed;
-      GlobalBlock->invokeDtor();
+      if (GlobalBlock->isInitialized())
+        GlobalBlock->invokeDtor();
     }
     return false;
   }

diff  --git a/clang/test/AST/ByteCode/typeid.cpp 
b/clang/test/AST/ByteCode/typeid.cpp
index aca18d4e25277..f4183691993d8 100644
--- a/clang/test/AST/ByteCode/typeid.cpp
+++ b/clang/test/AST/ByteCode/typeid.cpp
@@ -72,3 +72,16 @@ namespace TypeidPtrRegression {
   }
 }
 
+
+// Regression test for assertion failure in invokeDtor(). GH-173950
+namespace GH173950 {
+  struct A {
+    virtual void f();
+  };
+
+  static A &a = *new A;
+  extern A &a;
+
+  // This used to crash with: Assertion `IsInitialized' failed in invokeDtor()
+  const std::type_info &a_ti = typeid(a);
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to