[clang] 72fb188 - [clang][Interp] Handle Pointer::toAPValue() for expr bases (#101937)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 5 02:11:00 PDT 2024
Author: Timm Baeder
Date: 2024-08-05T11:10:56+02:00
New Revision: 72fb1889424fc371ef7d630009e4e579d18b9247
URL: https://github.com/llvm/llvm-project/commit/72fb1889424fc371ef7d630009e4e579d18b9247
DIFF: https://github.com/llvm/llvm-project/commit/72fb1889424fc371ef7d630009e4e579d18b9247.diff
LOG: [clang][Interp] Handle Pointer::toAPValue() for expr bases (#101937)
No reason to return early for them anymore.
Added:
Modified:
clang/lib/AST/Interp/Pointer.cpp
clang/test/AST/Interp/codegen.cpp
clang/test/AST/Interp/new-delete.cpp
Removed:
################################################################################
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 {{}} \
More information about the cfe-commits
mailing list