https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/226096
>From c037847fa56760b3daa58dc37c97bbae80c2711c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Thu, 24 Sep 2026 09:19:58 +0200 Subject: [PATCH] asdf --- clang/lib/AST/ByteCode/Compiler.cpp | 62 +++++++++++---------- clang/lib/AST/ByteCode/Pointer.cpp | 46 ++++++++++----- clang/lib/AST/ByteCode/Pointer.h | 1 + clang/test/CodeGenCXX/mangle-class-nttp.cpp | 3 + 4 files changed, 67 insertions(+), 45 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 16f2a768fe06cf..81c8fb0b9f17d7 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5922,7 +5922,6 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType, return this->emitNull(ValType, 0, nullptr, Info); APValue::LValueBase Base = Val.getLValueBase(); - ArrayRef<APValue::LValuePathEntry> Path = Val.getLValuePath(); if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>()) return this->visit(BaseExpr); @@ -5931,40 +5930,43 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType, return false; QualType EntryType = VD->getType(); - for (auto &Entry : Path) { - if (EntryType->isArrayType()) { - uint64_t Index = Entry.getAsArrayIndex(); - QualType ElemType = - EntryType->getAsArrayTypeUnsafe()->getElementType(); - if (!this->emitConst(Index, PT_Uint64, Info)) - return false; - if (!this->emitArrayElemPtrPop(PT_Uint64, Info)) - return false; - EntryType = ElemType; - } else { - assert(EntryType->isRecordType()); - const Record *EntryRecord = getRecord(EntryType); - if (!EntryRecord) - return false; - - const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer(); - if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) { - unsigned EntryOffset = EntryRecord->getField(FD)->Offset; - if (!this->emitGetPtrFieldPop(EntryOffset, Info)) + if (Val.hasLValuePath()) { + ArrayRef<APValue::LValuePathEntry> Path = Val.getLValuePath(); + for (auto &Entry : Path) { + if (EntryType->isArrayType()) { + uint64_t Index = Entry.getAsArrayIndex(); + QualType ElemType = + EntryType->getAsArrayTypeUnsafe()->getElementType(); + if (!this->emitConst(Index, PT_Uint64, Info)) + return false; + if (!this->emitArrayElemPtrPop(PT_Uint64, Info)) return false; - EntryType = FD->getType(); + EntryType = ElemType; } else { - const auto *Base = cast<CXXRecordDecl>(BaseOrMember); - if (const Record::Base *B = EntryRecord->getBaseOrNull(Base)) { - if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, Info)) + assert(EntryType->isRecordType()); + const Record *EntryRecord = getRecord(EntryType); + if (!EntryRecord) + return false; + + const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer(); + if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) { + unsigned EntryOffset = EntryRecord->getField(FD)->Offset; + if (!this->emitGetPtrFieldPop(EntryOffset, Info)) return false; + EntryType = FD->getType(); } else { - // Must be a virtual base. - assert(EntryRecord->findVirtualBase(Base)); - if (!this->emitGetPtrVirtBasePop(Base, Info)) - return false; + const auto *Base = cast<CXXRecordDecl>(BaseOrMember); + if (const Record::Base *B = EntryRecord->getBaseOrNull(Base)) { + if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, Info)) + return false; + } else { + // Must be a virtual base. + assert(EntryRecord->findVirtualBase(Base)); + if (!this->emitGetPtrVirtBasePop(Base, Info)) + return false; + } + EntryType = Ctx.getASTContext().getCanonicalTagType(Base); } - EntryType = Ctx.getASTContext().getCanonicalTagType(Base); } } } diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index bf9900cdab21f7..552cdf1bf8ec71 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -289,7 +289,24 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { CharUnits::fromQuantity(Offset * elemSize()), Path, /*OnePastTheEnd=*/false, /*IsNull=*/false); case Storage::Opaque: { - if (!Opaque.Base.getType()->isPointerType()) { + bool ValidBase = Opaque.hasValidBase() || this->Offset <= 1; + + size_t LayoutOffset = Opaque.computeLayoutOffset(ASTCtx).value_or(0); + size_t ElemSize = 0; + if (validType(Opaque.getFieldType())) + ElemSize = ASTCtx.getTypeSizeInChars(Opaque.getFieldType()).getQuantity(); + + auto LValueOffset = + CharUnits::fromQuantity(LayoutOffset + (this->Offset * ElemSize)); + APValue::LValueBase Base; + if (const Expr *E = Opaque.Base.asExpr()) + Base = E; + else + Base = Opaque.Base.asValueDecl(); + + // For valid bases, assemble the LValuePath. + APValue Result; + if (ValidBase) { for (const PointerPathEntry &Entry : Opaque.path()) { switch (Entry.Kind) { case PointerPathEntry::Field: @@ -307,21 +324,13 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { break; } } - } - size_t LayoutOffset = Opaque.computeLayoutOffset(ASTCtx).value_or(0); - size_t ElemSize = 0; - if (validType(Opaque.getFieldType())) - ElemSize = ASTCtx.getTypeSizeInChars(Opaque.getFieldType()).getQuantity(); - auto Offset = - CharUnits::fromQuantity(LayoutOffset + (this->Offset * ElemSize)); - APValue::LValueBase Base; - if (const Expr *E = Opaque.Base.asExpr()) - Base = E; - else - Base = Opaque.Base.asValueDecl(); - APValue Result = - APValue(Base, Offset, Path, Opaque.isOnePastEnd(), /*IsNullPtr=*/false); + Result = APValue(Base, LValueOffset, Path, Opaque.isOnePastEnd(), + /*IsNullPtr=*/false); + + } else { + Result = APValue(Base, LValueOffset, APValue::NoLValuePath{}); + } Result.setConstexprUnknown(Opaque.isConstexprUnknown()); return Result; } @@ -1575,3 +1584,10 @@ bool OpaquePointer::isOnePastEndOrElementPastEnd() const { return false; } + +bool OpaquePointer::hasValidBase() const { + if (const VarDecl *VD = Base.asVarDecl()) + return !VD->hasExternalStorage(); + + return !Base.getType()->isPointerType(); +} diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 35a0645ff34c63..207ec06a32a34d 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -447,6 +447,7 @@ struct OpaquePointer { bool hasDeclBase() const { return Base.isDecl(); } const VarDecl *getBaseDecl() const { return Base.asVarDecl(); } const Expr *getBaseExpr() const { return Base.asExpr(); } + bool hasValidBase() const; OpaquePointer withFieldType(const Type *FieldTy, diff --git a/clang/test/CodeGenCXX/mangle-class-nttp.cpp b/clang/test/CodeGenCXX/mangle-class-nttp.cpp index 536592c6a93086..f818679d8bca82 100644 --- a/clang/test/CodeGenCXX/mangle-class-nttp.cpp +++ b/clang/test/CodeGenCXX/mangle-class-nttp.cpp @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-windows -emit-llvm -o - | FileCheck %s --check-prefix=MSABI +// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-windows -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s --check-prefix=MSABI + #define fold(x) (__builtin_constant_p(x) ? (x) : (x)) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
