[clang] [clang][Interp] Handle Pointer::toAPValue() for expr bases (PR #101937)

via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 5 01:18:49 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

No reason to return early for them anymore.

---
Full diff: https://github.com/llvm/llvm-project/pull/101937.diff


3 Files Affected:

- (modified) clang/lib/AST/Interp/Pointer.cpp (+25-4) 
- (modified) clang/test/AST/Interp/codegen.cpp (+10) 
- (modified) clang/test/AST/Interp/new-delete.cpp (+1-1) 


``````````diff
diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp
index f86be1214826d..2b1f8b460510c 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -16,6 +16,7 @@
 #include "MemberPointer.h"
 #include "PrimType.h"
 #include "Record.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
 
 using namespace clang;
@@ -155,12 +156,32 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
   APValue::LValueBase Base;
   if (const auto *VD = Desc->asValueDecl())
     Base = VD;
-  else if (const auto *E = Desc->asExpr())
-    Base = E;
-  else
+  else if (const auto *E = Desc->asExpr()) {
+    // Create a DynamicAlloc base of the right type.
+    if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) {
+      QualType AllocatedType;
+      if (NewExpr->isArray()) {
+        assert(Desc->isArray());
+        APInt ArraySize(64, static_cast<uint64_t>(Desc->getNumElems()),
+                        /*IsSigned=*/false);
+        AllocatedType =
+            ASTCtx.getConstantArrayType(NewExpr->getAllocatedType(), ArraySize,
+                                        nullptr, ArraySizeModifier::Normal, 0);
+      } else {
+        AllocatedType = NewExpr->getAllocatedType();
+      }
+      // FIXME: Suboptimal counting of dynamic allocations. Move this to Context
+      // or InterpState?
+      static int ReportedDynamicAllocs = 0;
+      DynamicAllocLValue DA(ReportedDynamicAllocs++);
+      Base = APValue::LValueBase::getDynamicAlloc(DA, AllocatedType);
+    } else {
+      Base = E;
+    }
+  } else
     llvm_unreachable("Invalid allocation type");
 
-  if (isUnknownSizeArray() || Desc->asExpr())
+  if (isUnknownSizeArray())
     return APValue(Base, CharUnits::Zero(), Path,
                    /*IsOnePastEnd=*/isOnePastEnd(), /*IsNullPtr=*/false);
 
diff --git a/clang/test/AST/Interp/codegen.cpp b/clang/test/AST/Interp/codegen.cpp
index f1f0a33673a5b..42d98a079e120 100644
--- a/clang/test/AST/Interp/codegen.cpp
+++ b/clang/test/AST/Interp/codegen.cpp
@@ -32,6 +32,16 @@ namespace BaseClassOffsets {
   B* b = &c;
 }
 
+namespace ExprBase {
+  struct A { int n; };
+  struct B { int n; };
+  struct C : A, B {};
+
+  extern const int &&t = ((B&&)C{}).n;
+  // CHECK: @_ZGRN8ExprBase1tE_ = internal global {{.*}} zeroinitializer,
+  // CHECK: @_ZN8ExprBase1tE = constant ptr {{.*}} @_ZGRN8ExprBase1tE_, {{.*}} 8
+}
+
 namespace reinterpretcast {
   const unsigned int n = 1234;
   extern const int &s = reinterpret_cast<const int&>(n);
diff --git a/clang/test/AST/Interp/new-delete.cpp b/clang/test/AST/Interp/new-delete.cpp
index ddf91005c61d9..325ce27c6d51d 100644
--- a/clang/test/AST/Interp/new-delete.cpp
+++ b/clang/test/AST/Interp/new-delete.cpp
@@ -358,7 +358,7 @@ namespace delete_random_things {
                                              // both-note {{delete of pointer to subobject }}
   static_assert((delete (new int + 1), true)); // both-error {{}} \
                                                // ref-note {{delete of pointer '&{*new int#0} + 1' that does not point to complete object}} \
-                                               // expected-note {{delete of pointer '&new int + 1' that does not point to complete object}}
+                                               // expected-note {{delete of pointer '&{*new int#1} + 1' that does not point to complete object}}
   static_assert((delete[] (new int[3] + 1), true)); // both-error {{}} \
                                                     // both-note {{delete of pointer to subobject}}
   static_assert((delete &(int&)(int&&)0, true)); // both-error {{}} \

``````````

</details>


https://github.com/llvm/llvm-project/pull/101937


More information about the cfe-commits mailing list