[clang] 3b8f9a2 - [clang][bytecode] Loosen assertion This() for array elements (#130399)

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 8 04:13:56 PST 2025


Author: Timm Baeder
Date: 2025-03-08T13:13:52+01:00
New Revision: 3b8f9a228c5f12f282778b18117b9a88c07e87cb

URL: https://github.com/llvm/llvm-project/commit/3b8f9a228c5f12f282778b18117b9a88c07e87cb
DIFF: https://github.com/llvm/llvm-project/commit/3b8f9a228c5f12f282778b18117b9a88c07e87cb.diff

LOG: [clang][bytecode] Loosen assertion This() for array elements (#130399)

getRecord() returns null on array elements, even for composite arrays.
The assertion here was overly restrictive and having an array element as
instance pointer should be fine otherwise.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 401bbefaf9a92..f2ddeac99cd7e 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2432,9 +2432,12 @@ inline bool This(InterpState &S, CodePtr OpPC) {
   // Ensure the This pointer has been cast to the correct base.
   if (!This.isDummy()) {
     assert(isa<CXXMethodDecl>(S.Current->getFunction()->getDecl()));
-    assert(This.getRecord());
+    [[maybe_unused]] const Record *R = This.getRecord();
+    if (!R)
+      R = This.narrow().getRecord();
+    assert(R);
     assert(
-        This.getRecord()->getDecl() ==
+        R->getDecl() ==
         cast<CXXMethodDecl>(S.Current->getFunction()->getDecl())->getParent());
   }
 

diff  --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp
index 7a4fc89a27dac..c353162a7aab0 100644
--- a/clang/test/AST/ByteCode/placement-new.cpp
+++ b/clang/test/AST/ByteCode/placement-new.cpp
@@ -339,6 +339,30 @@ namespace PR48606 {
   static_assert(f());
 }
 
+/// This used to crash because of an assertion in the implementation
+/// of the This instruction.
+namespace ExplicitThisOnArrayElement {
+  struct S {
+    int a = 12;
+    constexpr S(int a) {
+      this->a = a;
+    }
+  };
+
+  template <class _Tp, class... _Args>
+  constexpr void construct_at(_Tp *__location, _Args &&...__args) {
+    new (__location) _Tp(__args...);
+  }
+
+  constexpr bool foo() {
+    auto *M = std::allocator<S>().allocate(13); // both-note {{allocation performed here was not deallocated}}
+    construct_at(M, 12);
+    return true;
+  }
+
+  static_assert(foo()); // both-error {{not an integral constant expression}}
+}
+
 #ifdef BYTECODE
 constexpr int N = [] // expected-error {{must be initialized by a constant expression}} \
                      // expected-note {{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} \


        


More information about the cfe-commits mailing list