llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> Set the source type when allocating primitives so we can later retrieve it. --- Full diff: https://github.com/llvm/llvm-project/pull/132544.diff 7 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+4-3) - (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+4-3) - (modified) clang/lib/AST/ByteCode/Descriptor.h (+2-2) - (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+18-20) - (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3) - (modified) clang/lib/AST/ByteCode/Program.h (+4-2) - (modified) clang/test/AST/ByteCode/placement-new.cpp (+15) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 91640c4eb5cf9..bdef06d95eb77 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -3354,7 +3354,8 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) { if (E->isArray()) Desc = nullptr; // We're not going to use it in this case. else - Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD, + Desc = P.createDescriptor(E, *ElemT, /*SourceTy=*/nullptr, + Descriptor::InlineDescMD, /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false); } else { @@ -4258,8 +4259,8 @@ unsigned Compiler<Emitter>::allocateLocalPrimitive( // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g. // (int){12} in C. Consider using Expr::isTemporaryObject() instead // or isa<MaterializeTemporaryExpr>(). - Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst, - isa<const Expr *>(Src)); + Descriptor *D = P.createDescriptor(Src, Ty, nullptr, Descriptor::InlineDescMD, + IsConst, isa<const Expr *>(Src)); Scope::Local Local = this->createLocal(D); if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) Locals.insert({VD, Local}); diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 0f862583a37b1..15b2fe02fb875 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -329,9 +329,10 @@ static BlockMoveFn getMoveArrayPrim(PrimType Type) { } /// Primitives. -Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, - bool IsConst, bool IsTemporary, bool IsMutable) - : Source(D), ElemSize(primSize(Type)), Size(ElemSize), +Descriptor::Descriptor(const DeclTy &D, const Type *SourceTy, PrimType Type, + MetadataSize MD, bool IsConst, bool IsTemporary, + bool IsMutable) + : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), PrimT(Type), IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)), diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index dfb008e4c8b8a..35c84a7847a72 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -175,8 +175,8 @@ struct Descriptor final { const BlockMoveFn MoveFn = nullptr; /// Allocates a descriptor for a primitive. - Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsConst, - bool IsTemporary, bool IsMutable); + Descriptor(const DeclTy &D, const Type *SourceTy, PrimType Type, + MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable); /// Allocates a descriptor for an array of primitives. Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, size_t NumElems, diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 57037b674feba..d847489557bc3 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -149,6 +149,18 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, #undef RET_CASE } +static QualType getElemType(const Pointer &P) { + const Descriptor *Desc = P.getFieldDesc(); + QualType T = Desc->getType(); + if (Desc->isPrimitive()) + return T; + if (T->isPointerType()) + return T->getAs<PointerType>()->getPointeeType(); + if (Desc->isArray()) + return Desc->getElemQualType(); + return T; +} + static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID) { auto Loc = S.Current->getSource(OpPC); @@ -1572,10 +1584,10 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, return true; } - const Descriptor *Desc = - S.P.createDescriptor(NewCall, *ElemT, Descriptor::InlineDescMD, - /*IsConst=*/false, /*IsTemporary=*/false, - /*IsMutable=*/false); + const Descriptor *Desc = S.P.createDescriptor( + NewCall, *ElemT, ElemType.getTypePtr(), Descriptor::InlineDescMD, + /*IsConst=*/false, /*IsTemporary=*/false, + /*IsMutable=*/false); Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(), DynamicAllocator::Form::Operator); assert(B); @@ -1779,15 +1791,13 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, if (DestPtr.isDummy() || SrcPtr.isDummy()) return false; - QualType DestElemType; + QualType DestElemType = getElemType(DestPtr); size_t RemainingDestElems; if (DestPtr.getFieldDesc()->isArray()) { - DestElemType = DestPtr.getFieldDesc()->getElemQualType(); RemainingDestElems = DestPtr.isUnknownSizeArray() ? 0 : (DestPtr.getNumElems() - DestPtr.getIndex()); } else { - DestElemType = DestPtr.getType(); RemainingDestElems = 1; } unsigned DestElemSize = ASTCtx.getTypeSizeInChars(DestElemType).getQuantity(); @@ -1800,15 +1810,13 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, return false; } - QualType SrcElemType; + QualType SrcElemType = getElemType(SrcPtr); size_t RemainingSrcElems; if (SrcPtr.getFieldDesc()->isArray()) { - SrcElemType = SrcPtr.getFieldDesc()->getElemQualType(); RemainingSrcElems = SrcPtr.isUnknownSizeArray() ? 0 : (SrcPtr.getNumElems() - SrcPtr.getIndex()); } else { - SrcElemType = SrcPtr.getType(); RemainingSrcElems = 1; } unsigned SrcElemSize = ASTCtx.getTypeSizeInChars(SrcElemType).getQuantity(); @@ -1881,16 +1889,6 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, bool IsWide = (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp); - auto getElemType = [](const Pointer &P) -> QualType { - const Descriptor *Desc = P.getFieldDesc(); - QualType T = Desc->getType(); - if (T->isPointerType()) - return T->getAs<PointerType>()->getPointeeType(); - if (Desc->isArray()) - return Desc->getElemQualType(); - return T; - }; - const ASTContext &ASTCtx = S.getASTContext(); QualType ElemTypeA = getElemType(PtrA); QualType ElemTypeB = getElemType(PtrB); diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 665e87bb5d2c8..c83f5579fd55f 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -166,7 +166,7 @@ unsigned Program::getOrCreateDummy(const DeclTy &D) { Descriptor *Desc; if (std::optional<PrimType> T = Ctx.classify(QT)) - Desc = createDescriptor(D, *T, std::nullopt, /*IsTemporary=*/true, + Desc = createDescriptor(D, *T, nullptr, std::nullopt, /*IsTemporary=*/true, /*IsMutable=*/false); else Desc = createDescriptor(D, QT.getTypePtr(), std::nullopt, @@ -244,7 +244,8 @@ std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty, const bool IsConst = Ty.isConstQualified(); const bool IsTemporary = D.dyn_cast<const Expr *>(); if (std::optional<PrimType> T = Ctx.classify(Ty)) - Desc = createDescriptor(D, *T, Descriptor::GlobalMD, IsConst, IsTemporary); + Desc = createDescriptor(D, *T, nullptr, Descriptor::GlobalMD, IsConst, + IsTemporary); else Desc = createDescriptor(D, Ty.getTypePtr(), Descriptor::GlobalMD, IsConst, IsTemporary); @@ -365,7 +366,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { const bool IsMutable = FD->isMutable(); const Descriptor *Desc; if (std::optional<PrimType> T = Ctx.classify(FT)) { - Desc = createDescriptor(FD, *T, std::nullopt, IsConst, + Desc = createDescriptor(FD, *T, nullptr, std::nullopt, IsConst, /*isTemporary=*/false, IsMutable); } else { Desc = createDescriptor(FD, FT.getTypePtr(), std::nullopt, IsConst, diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h index d503652abb96f..ce206260c702a 100644 --- a/clang/lib/AST/ByteCode/Program.h +++ b/clang/lib/AST/ByteCode/Program.h @@ -115,11 +115,13 @@ class Program final { Record *getOrCreateRecord(const RecordDecl *RD); /// Creates a descriptor for a primitive type. - Descriptor *createDescriptor(const DeclTy &D, PrimType Type, + Descriptor *createDescriptor(const DeclTy &D, PrimType T, + const Type *SourceTy = nullptr, Descriptor::MetadataSize MDSize = std::nullopt, bool IsConst = false, bool IsTemporary = false, bool IsMutable = false) { - return allocateDescriptor(D, Type, MDSize, IsConst, IsTemporary, IsMutable); + return allocateDescriptor(D, SourceTy, T, MDSize, IsConst, IsTemporary, + IsMutable); } /// Creates a descriptor for a composite type. diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index c353162a7aab0..14b893c7e587b 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -376,3 +376,18 @@ constexpr int N = [] // expected-error {{must be initialized by a constant expre return s.a[0]; }(); #endif + +namespace MemMove { + constexpr int foo() { + int *a = std::allocator<int>{}.allocate(1); + new(a) int{123}; + + int b; + __builtin_memmove(&b, a, sizeof(int)); + + std::allocator<int>{}.deallocate(a); + return b; + } + + static_assert(foo() == 123); +} `````````` </details> https://github.com/llvm/llvm-project/pull/132544 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits