aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-22 15:02:29 +0000
committer_ov4 <ov4@ov4.org>2026-10-22 15:21:11 +0000
commit353c38e23108856daa2c5d0e86443ac5136dcaa7 (patch)
treebd899dd541543d6fa875d534a7d571b2baa087b0 /lib
parent9ef1cc2424e5afa21d3980b56046f5fb71bff89f (diff)
fix(codegen): skip IR verification after reported errors
Verify the module only when no error was reported, and let defineRecord skip bad fields and still set the record body, marking it Invalid so later missing-field lookups stay silent. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CodeGen.cc4
-rw-r--r--lib/CodeGen/Designator.cc4
-rw-r--r--lib/CodeGen/TypeSystem.cc29
3 files changed, 24 insertions, 13 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index d81c4ff..e45a3db 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -364,7 +364,9 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
RuntimeChecker->emitStderr(Msg);
Builder->CreateRet(ConstantInt::get(Type::getInt32Ty(*TheContext), 1));
- if (verifyModule(*TheModule, &errs())) {
+ // After a reported error the IR may be incomplete; verifying it would only
+ // dump noise behind the real diagnostic.
+ if (!HadError && verifyModule(*TheModule, &errs())) {
errs() << cps::diagnosticPrefix(cps::Severity::Fatal, "") << "LLVM module verification failed\n";
HadError = true;
}
diff --git a/lib/CodeGen/Designator.cc b/lib/CodeGen/Designator.cc
index 4f0e82b..6737937 100644
--- a/lib/CodeGen/Designator.cc
+++ b/lib/CodeGen/Designator.cc
@@ -219,7 +219,9 @@ bool CodeGen::emitLValue(ExprAST *E, LValueInfo &Out) {
}
const RecordFieldInfo *FI = RP->findField(A.FieldName);
if (!FI) {
- reportError("Record type %s has no field %s", TypeName.c_str(), A.FieldName.c_str());
+ // The rejected field was already reported with its record.
+ if (!RP->Invalid)
+ reportError("Record type %s has no field %s", TypeName.c_str(), A.FieldName.c_str());
return false;
}
if (!FI->IsPublic && !sameIdentifier(CurrentClass, TypeName)) {
diff --git a/lib/CodeGen/TypeSystem.cc b/lib/CodeGen/TypeSystem.cc
index ee177fb..a567562 100644
--- a/lib/CodeGen/TypeSystem.cc
+++ b/lib/CodeGen/TypeSystem.cc
@@ -199,32 +199,38 @@ bool TypeSystem::defineRecord(const std::string &Name,
return false;
}
+ // A bad field is skipped so the record still gets a body; Err keeps the
+ // first diagnostic and Invalid silences follow-up missing-field errors.
std::vector<Type*> FieldTypes;
RecordPayload Payload;
+ auto Bad = [&](std::string Message) {
+ if (!Payload.Invalid) Err = std::move(Message);
+ Payload.Invalid = true;
+ };
for (const RecordFieldDecl &Field : Fields) {
const std::string &FieldName = Field.Name;
const std::string &FieldTypeName = Field.TypeName;
if (Payload.findField(FieldName)) {
- Err = "Duplicate field '" + FieldName + "' in record " + Name;
- return false;
+ Bad("Duplicate field '" + FieldName + "' in record " + Name);
+ continue;
}
const TypeInfo *FieldInfo = resolve(FieldTypeName);
if (!FieldInfo) {
- Err = "Unknown type " + FieldTypeName + " for field " + FieldName +
- " of record " + Name;
- return false;
+ Bad("Unknown type " + FieldTypeName + " for field " + FieldName +
+ " of record " + Name);
+ continue;
}
if (FieldInfo->isVoid()) {
- Err = "Field " + FieldName + " of record " + Name + " cannot be VOID";
- return false;
+ Bad("Field " + FieldName + " of record " + Name + " cannot be VOID");
+ continue;
}
// By-value record fields require a *completed* record (source order);
// this also rules out self/mutual inclusion. Inclusion via a pointer
// type is fine (opaque ptr, always complete).
if (FieldInfo->isRecord() && llvm::cast<StructType>(FieldInfo->LLVMType)->isOpaque()) {
- Err = "Record type " + FieldTypeName + " must be fully defined before field " +
- FieldName + " of record " + Name + " (records cannot contain themselves)";
- return false;
+ Bad("Record type " + FieldTypeName + " must be fully defined before field " +
+ FieldName + " of record " + Name + " (records cannot contain themselves)");
+ continue;
}
RecordFieldInfo FI;
@@ -236,8 +242,9 @@ bool TypeSystem::defineRecord(const std::string &Name,
}
llvm::cast<StructType>(It->second.LLVMType)->setBody(FieldTypes);
+ bool Ok = !Payload.Invalid;
It->second.Record = std::move(Payload);
- return true;
+ return Ok;
}
bool TypeSystem::definePointer(const std::string &Name,