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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits