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

Reply via email to