aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-22 15:17:31 +0000
committer_ov4 <ov4@ov4.org>2026-10-22 15:21:11 +0000
commitfe70048b33baebdfbf7071059bd4742ec16ab408 (patch)
tree040ab1e1d6847baf8b60b8c1970543b8e578e36f /lib/CodeGen
parent98ef8bc4dfcebe44eece933ff0affc776b7199dd (diff)
fix(classes): defer NEW for DECLARE without a parameterless constructor
A plain DECLARE, field or array element now calls NEW only when the class has a parameterless one; otherwise the zeroed object waits for x <- NEW C(...), as in guide section 10.2. DECLARE with parentheses still requires a matching constructor. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/ConstructorGen.cc10
-rw-r--r--lib/CodeGen/ValueTypeGen.cc6
2 files changed, 13 insertions, 3 deletions
diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc
index 8ca0258..286435e 100644
--- a/lib/CodeGen/ConstructorGen.cc
+++ b/lib/CodeGen/ConstructorGen.cc
@@ -114,8 +114,16 @@ bool CodeGen::emitConstruct(const std::string &TypeName, Value *Addr,
return true;
}
+// Guide 10.2 creation pattern: a plain DECLARE only runs NEW when the class has
+// a parameterless one; otherwise the object stays zeroed (fields constructed)
+// and a later `x <- NEW C(...)` binds it.
bool CodeGen::emitDefaultConstruct(const std::string &TypeName, Value *Addr, int Line) {
- return emitConstruct(TypeName, Addr, {}, Line);
+ const TypeInfo *Info = resolveType(TypeName);
+ if (!Info) return false;
+ for (const FuncSig *Sig : FuncGen->getOverloads(TypeName + ".NEW"))
+ if (Sig->Params.empty()) return emitConstruct(TypeName, Addr, {}, Line);
+ SaveAndRestore<int> Location(DiagnosticLine, Line);
+ return !Info->asRecord() || emitFieldDefaults(Info, Addr, Line);
}
// Default-constructs, in declaration order, each field of the record at Addr
diff --git a/lib/CodeGen/ValueTypeGen.cc b/lib/CodeGen/ValueTypeGen.cc
index e73b189..af32d74 100644
--- a/lib/CodeGen/ValueTypeGen.cc
+++ b/lib/CodeGen/ValueTypeGen.cc
@@ -262,6 +262,8 @@ void CodeGen::emitDeclareStmt(DeclareStmtAST *Stmt) {
reportError("Constructor arguments require a class type");
return;
}
- if (emitConstruct(Info->Name, Alloca, Stmt->getArgs(), Stmt->getLine()))
- activateStackObject(Lifetime);
+ bool Constructed = Stmt->hasParens()
+ ? emitConstruct(Info->Name, Alloca, Stmt->getArgs(), Stmt->getLine())
+ : emitDefaultConstruct(Info->Name, Alloca, Stmt->getLine());
+ if (Constructed) activateStackObject(Lifetime);
}