Skip to content

Conversation

@tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Mar 4, 2025

Later operations on these are invalid, but the declaration is fine, if extern.

Later operations on these are invalid, but the declaration is fine,
if extern.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Mar 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 4, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

Later operations on these are invalid, but the declaration is fine, if extern.


Full diff: https://github.com/llvm/llvm-project/pull/129685.diff

6 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Descriptor.h (+2-2)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+6-1)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+1)
  • (modified) clang/test/AST/ByteCode/records.cpp (+12)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 74f5d6ebd9ca6..fc1ccce6040ce 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2843,6 +2843,8 @@ bool Compiler<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
 
   assert(Initializing);
   const Record *R = P.getOrCreateRecord(E->getLambdaClass());
+  if (!R)
+    return false;
 
   auto *CaptureInitIt = E->capture_init_begin();
   // Initialize all fields (which represent lambda captures) of the
@@ -4076,9 +4078,8 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
     } else if (D->isRecord()) {
       if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
         return false;
-    } else {
-      assert(false);
-    }
+    } else
+      return false;
 
     if (!this->emitFinishInitPop(E))
       return false;
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp
index 6017f6dd61cb3..0e6e42186e9d5 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -402,10 +402,10 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD,
 }
 
 /// Dummy.
-Descriptor::Descriptor(const DeclTy &D)
-    : Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
-      ElemRecord(nullptr), IsConst(true), IsMutable(false), IsTemporary(false),
-      IsDummy(true) {
+Descriptor::Descriptor(const DeclTy &D, MetadataSize MD)
+    : Source(D), ElemSize(1), Size(1), MDSize(MD.value_or(0)),
+      AllocSize(MDSize), ElemRecord(nullptr), IsConst(true), IsMutable(false),
+      IsTemporary(false), IsDummy(true) {
   assert(Source && "Missing source");
 }
 
diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h
index 01fa4b198de67..347f091d9550d 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -198,7 +198,7 @@ struct Descriptor final {
              bool IsTemporary, bool IsMutable);
 
   /// Allocates a dummy descriptor.
-  Descriptor(const DeclTy &D);
+  Descriptor(const DeclTy &D, MetadataSize MD = std::nullopt);
 
   /// Make this descriptor a dummy descriptor.
   void makeDummy() { IsDummy = true; }
@@ -261,7 +261,7 @@ struct Descriptor final {
   bool isUnknownSizeArray() const { return Size == UnknownSizeMark; }
 
   /// Checks if the descriptor is of a primitive.
-  bool isPrimitive() const { return !IsArray && !ElemRecord; }
+  bool isPrimitive() const { return !IsArray && !ElemRecord && !IsDummy; }
 
   /// Checks if the descriptor is of an array.
   bool isArray() const { return IsArray; }
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 92cfa192fd385..634ec316320c3 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -248,7 +248,12 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
         Index = Ptr.getIndex();
 
       QualType ElemType = Desc->getElemQualType();
-      Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
+      if (const auto *RD = ElemType->getAsRecordDecl();
+          RD && !RD->getDefinition()) {
+        // Ignore this for the offset.
+      } else {
+        Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
+      }
       if (Ptr.getArray().getType()->isArrayType())
         Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
       Ptr = Ptr.getArray();
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 0754e259b7cb3..96f2565a3d936 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -393,6 +393,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
     if (const auto *Record = getOrCreateRecord(RT->getDecl()))
       return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary,
                                 IsMutable);
+    return allocateDescriptor(D, MDSize);
   }
 
   // Arrays.
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index cb3d6111fd2bf..42b6d82d7190b 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1747,3 +1747,15 @@ namespace CtorOfInvalidClass {
   template<ReferenceOf<InvalidCtor> auto R, typename Rep> int F; // both-error {{non-type template argument is not a constant expression}}
 #endif
 }
+
+namespace IncompleteTypes {
+  struct Incomplete;
+
+  constexpr bool foo() {
+    extern Incomplete bounded[10];
+    extern Incomplete unbounded[];
+    extern Incomplete IT;
+    return true;
+  }
+  static_assert(foo(), "");
+}

@tbaederr tbaederr merged commit 06fc7d6 into llvm:main Mar 4, 2025
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants