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::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::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 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(), ""); +}