[clang] 06fc7d6 - [clang][bytecode] Don't error out on incomplete declarations (#129685)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 4 03:41:37 PST 2025
Author: Timm Baeder
Date: 2025-03-04T12:41:34+01:00
New Revision: 06fc7d68ff816090ea8654a5a0240a4444a8eb6f
URL: https://github.com/llvm/llvm-project/commit/06fc7d68ff816090ea8654a5a0240a4444a8eb6f
DIFF: https://github.com/llvm/llvm-project/commit/06fc7d68ff816090ea8654a5a0240a4444a8eb6f.diff
LOG: [clang][bytecode] Don't error out on incomplete declarations (#129685)
Later operations on these are invalid, but the declaration is fine, if
extern.
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/lib/AST/ByteCode/Descriptor.cpp
clang/lib/AST/ByteCode/Descriptor.h
clang/lib/AST/ByteCode/Pointer.cpp
clang/lib/AST/ByteCode/Program.cpp
clang/test/AST/ByteCode/records.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 96f67ffca43b3..394e39e99a106 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
@@ -4087,9 +4089,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 bcd9f6f3d078a..0f862583a37b1 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -404,10 +404,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 8ce99731ee0ae..dfb008e4c8b8a 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -200,7 +200,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; }
@@ -263,7 +263,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 e5876409edcf7..324097a95dda3 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 cc2cfc9b03b41..c33d7fd7a2dc5 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(), "");
+}
More information about the cfe-commits
mailing list