llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> The added test case is still diagnosed differently, but I'm not sure which version is better. --- Full diff: https://github.com/llvm/llvm-project/pull/110121.diff 5 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+12-11) - (modified) clang/lib/AST/ByteCode/Compiler.h (+3-3) - (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+9) - (modified) clang/lib/AST/ByteCode/Descriptor.h (+2) - (modified) clang/test/AST/ByteCode/cxx23.cpp (+20) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6e3ea6bd070bc1..93008acde65f9d 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5293,7 +5293,7 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) { if (!D->isPrimitive() && !D->isPrimitiveArray()) { if (!this->emitGetPtrField(Field.Offset, SourceInfo{})) return false; - if (!this->emitDestruction(D)) + if (!this->emitDestruction(D, SourceInfo{})) return false; if (!this->emitPopPtr(SourceInfo{})) return false; @@ -5307,7 +5307,7 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) { if (!this->emitGetPtrBase(Base.Offset, SourceInfo{})) return false; - if (!this->emitRecordDestruction(Base.R)) + if (!this->emitRecordDestruction(Base.R, {})) return false; if (!this->emitPopPtr(SourceInfo{})) return false; @@ -6148,7 +6148,7 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS, /// on the stack. /// Emit destruction of record types (or arrays of record types). template <class Emitter> -bool Compiler<Emitter>::emitRecordDestruction(const Record *R) { +bool Compiler<Emitter>::emitRecordDestruction(const Record *R, SourceInfo Loc) { assert(R); assert(!R->isAnonymousUnion()); const CXXDestructorDecl *Dtor = R->getDestructor(); @@ -6161,15 +6161,16 @@ bool Compiler<Emitter>::emitRecordDestruction(const Record *R) { return false; assert(DtorFunc->hasThisPointer()); assert(DtorFunc->getNumParams() == 1); - if (!this->emitDupPtr(SourceInfo{})) + if (!this->emitDupPtr(Loc)) return false; - return this->emitCall(DtorFunc, 0, SourceInfo{}); + return this->emitCall(DtorFunc, 0, Loc); } /// When calling this, we have a pointer of the local-to-destroy /// on the stack. /// Emit destruction of record types (or arrays of record types). template <class Emitter> -bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) { +bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc, + SourceInfo Loc) { assert(Desc); assert(!Desc->isPrimitive()); assert(!Desc->isPrimitiveArray()); @@ -6193,13 +6194,13 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) { } for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) { - if (!this->emitConstUint64(I, SourceInfo{})) + if (!this->emitConstUint64(I, Loc)) return false; - if (!this->emitArrayElemPtrUint64(SourceInfo{})) + if (!this->emitArrayElemPtrUint64(Loc)) return false; - if (!this->emitDestruction(ElemDesc)) + if (!this->emitDestruction(ElemDesc, Loc)) return false; - if (!this->emitPopPtr(SourceInfo{})) + if (!this->emitPopPtr(Loc)) return false; } return true; @@ -6209,7 +6210,7 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) { if (Desc->ElemRecord->isAnonymousUnion()) return true; - return this->emitRecordDestruction(Desc->ElemRecord); + return this->emitRecordDestruction(Desc->ElemRecord, Loc); } namespace clang { diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 2dfa187713a803..94c0a5cb295b08 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -364,8 +364,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); - bool emitRecordDestruction(const Record *R); - bool emitDestruction(const Descriptor *Desc); + bool emitRecordDestruction(const Record *R, SourceInfo Loc); + bool emitDestruction(const Descriptor *Desc, SourceInfo Loc); unsigned collectBaseOffset(const QualType BaseType, const QualType DerivedType); bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD); @@ -540,7 +540,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> { if (!this->Ctx->emitGetPtrLocal(Local.Offset, E)) return false; - if (!this->Ctx->emitDestruction(Local.Desc)) + if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc())) return false; if (!this->Ctx->emitPopPtr(E)) diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 05ece907af42f4..44a7b88b2a1ee9 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -15,6 +15,7 @@ #include "Pointer.h" #include "PrimType.h" #include "Record.h" +#include "Source.h" using namespace clang; using namespace clang::interp; @@ -423,6 +424,14 @@ SourceLocation Descriptor::getLocation() const { llvm_unreachable("Invalid descriptor type"); } +SourceInfo Descriptor::getLoc() const { + if (const auto *D = Source.dyn_cast<const Decl *>()) + return SourceInfo(D); + if (const auto *E = Source.dyn_cast<const Expr *>()) + return SourceInfo(E); + llvm_unreachable("Invalid descriptor type"); +} + bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); } InitMap::InitMap(unsigned N) diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index 82f90430f7f4e5..5460199e0e991a 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -21,6 +21,7 @@ namespace clang { namespace interp { class Block; class Record; +class SourceInfo; struct InitMap; struct Descriptor; enum PrimType : unsigned; @@ -194,6 +195,7 @@ struct Descriptor final { QualType getType() const; QualType getElemQualType() const; SourceLocation getLocation() const; + SourceInfo getLoc() const; const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } const Expr *asExpr() const { return Source.dyn_cast<const Expr *>(); } diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp index 9d7e9d753e6d2f..3c50c8927304c0 100644 --- a/clang/test/AST/ByteCode/cxx23.cpp +++ b/clang/test/AST/ByteCode/cxx23.cpp @@ -269,3 +269,23 @@ namespace AnonUnionDtor { void bar() { foo(); } } + +/// FIXME: The two interpreters disagree about there to diagnose the non-constexpr destructor call. +namespace NonLiteralDtorInParam { + class NonLiteral { // all20-note {{is not an aggregate and has no constexpr constructors other than copy or move constructors}} + public: + NonLiteral() {} + ~NonLiteral() {} // all23-note {{declared here}} + }; + constexpr int F2(NonLiteral N) { // all20-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} \ + // ref23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}} + return 8; + } + + + void test() { + NonLiteral L; + constexpr auto D = F2(L); // all23-error {{must be initialized by a constant expression}} \ + // expected23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}} + } +} `````````` </details> https://github.com/llvm/llvm-project/pull/110121 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits