Author: Timm Baeder
Date: 2025-11-22T05:18:18Z
New Revision: 3841e7d818de2b7581351c6de3bfc9b13bdaeb30

URL: 
https://github.com/llvm/llvm-project/commit/3841e7d818de2b7581351c6de3bfc9b13bdaeb30
DIFF: 
https://github.com/llvm/llvm-project/commit/3841e7d818de2b7581351c6de3bfc9b13bdaeb30.diff

LOG: [clang][bytecode] Don't call getThis() on the bottom function frame 
(#169044)

We can't access the calling frame in that case.

Fixes https://github.com/llvm/llvm-project/issues/169032

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Interp.cpp
    clang/lib/AST/ByteCode/InterpFrame.h
    clang/test/AST/ByteCode/new-delete.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 280911c324bb1..4222fd97a84fa 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1407,7 +1407,8 @@ bool CheckLiteralType(InterpState &S, CodePtr OpPC, const 
Type *T) {
   //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677
   // Therefore, we use the C++1y behavior.
 
-  if (S.Current->getFunction() && S.Current->getFunction()->isConstructor() &&
+  if (!S.Current->isBottomFrame() &&
+      S.Current->getFunction()->isConstructor() &&
       S.Current->getThis().getDeclDesc()->asDecl() == S.EvaluatingDecl) {
     return true;
   }

diff  --git a/clang/lib/AST/ByteCode/InterpFrame.h 
b/clang/lib/AST/ByteCode/InterpFrame.h
index fa9de2e1e7c6d..febef1097ea8a 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.h
+++ b/clang/lib/AST/ByteCode/InterpFrame.h
@@ -109,6 +109,7 @@ class InterpFrame final : public Frame {
   /// Returns the 'this' pointer.
   const Pointer &getThis() const {
     assert(hasThisPointer());
+    assert(!isBottomFrame());
     return stackRef<Pointer>(ThisPointerOffset);
   }
 
@@ -116,6 +117,7 @@ class InterpFrame final : public Frame {
   const Pointer &getRVOPtr() const {
     assert(Func);
     assert(Func->hasRVO());
+    assert(!isBottomFrame());
     return stackRef<Pointer>(0);
   }
 

diff  --git a/clang/test/AST/ByteCode/new-delete.cpp 
b/clang/test/AST/ByteCode/new-delete.cpp
index 9e0f33e212c18..43e1f6bfcc9a6 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -1114,6 +1114,18 @@ namespace ZeroSizeArray {
   static_assert(foo() == 0);
 }
 
+namespace NonLiteralType {
+  /// This used to crash.
+  constexpr void foo() {
+    struct O {};
+
+    struct S {
+      O *s;
+      constexpr S() : s{std::allocator<O>{}.allocate(1)} {}
+    };
+  }
+}
+
 #else
 /// Make sure we reject this prior to C++20
 constexpr int a() { // both-error {{never produces a constant expression}}


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

Reply via email to