Bug 3986 – Struct constructors bypass default initialization of member variables

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-03-19T16:13:00Z
Last change time
2015-06-09T01:27:03Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
clugdbug

Comments

Comment #0 by clugdbug — 2010-03-19T16:13:43Z
If a struct constructor is called implicitly, member variables are not default initialized. Applies to D2.036 and later. Here's a simple test case with an assert that fails. (Beware: this test case doesn't capture the more complex case where one of the members is itself a struct with a constructor). I'm pretty sure the problem is in declaration.c, around line 1140. struct SiberianHamster { int rat = 813; this(string z) { } } void main() { SiberianHamster basil = "cybil"; assert(basil.rat == 813); }
Comment #1 by clugdbug — 2010-03-20T00:26:22Z
PATCH: In VarDeclaration::semantic, it should be doing a blit of the default initializer before it calls the constructor. Currently it only does that for explicit constructor calls. This bug as a blocker, since it makes struct invariants unusable: if a struct with a class invariant is used as a member of another struct, the invariant will fail on first use of that struct. Index: declaration.c =================================================================== --- declaration.c (revision 418) +++ declaration.c (working copy) @@ -1139,6 +1139,14 @@ // Rewrite as e1.ctor(arguments) Expression *ector = new DotIdExp(loc, e1, Id::ctor); ei->exp = new CallExp(loc, ector, ei->exp); + /* Before calling the constructor, initialize + * variable with a bit copy of the default + * initializer + */ + Expression *e = new AssignExp(loc, e1, t->defaultInit(loc)); + e->op = TOKblit; + e->type = t; + ei->exp = new CommaExp(loc, e, ei->exp); } else /* Look for opCall
Comment #2 by bugzilla — 2010-03-27T00:34:11Z
changeset 421
Comment #3 by clugdbug — 2010-04-10T12:45:32Z
Fixed DMD2.043.