@@ -72,6 +72,113 @@ extern (C++) bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad,
7272 return result;
7373}
7474
75+ /* **********************************************
76+ * Mark variable v as modified if it is inside a constructor that var
77+ * is a field in.
78+ */
79+ private int modifyFieldVar (Loc loc, Scope* sc, VarDeclaration var, Expression e1)
80+ {
81+ // printf("modifyFieldVar(var = %s)\n", var.toChars());
82+ Dsymbol s = sc.func;
83+ while (1 )
84+ {
85+ FuncDeclaration fd = null ;
86+ if (s)
87+ fd = s.isFuncDeclaration();
88+ if (fd &&
89+ ((fd.isCtorDeclaration() && var.isField()) ||
90+ (fd.isStaticCtorDeclaration() && ! var.isField())) &&
91+ fd.toParent2() == var.toParent2() &&
92+ (! e1 || e1.op == TOKthis))
93+ {
94+ bool result = true ;
95+
96+ var.ctorinit = true ;
97+ // printf("setting ctorinit\n");
98+
99+ if (var.isField() && sc.fieldinit && ! sc.intypeof)
100+ {
101+ assert (e1);
102+ auto mustInit = ((var.storage_class & STCnodefaultctor) != 0 ||
103+ var.type.needsNested());
104+
105+ auto dim = sc.fieldinit_dim;
106+ auto ad = fd.isMember2();
107+ assert (ad);
108+ size_t i;
109+ for (i = 0 ; i < dim; i++ ) // same as findFieldIndexByName in ctfeexp.c ?
110+ {
111+ if (ad.fields[i] == var)
112+ break ;
113+ }
114+ assert (i < dim);
115+ uint fi = sc.fieldinit[i];
116+
117+ if (fi & CSXthis_ctor)
118+ {
119+ if (var.type.isMutable() && e1.type.isMutable())
120+ result = false ;
121+ else
122+ {
123+ const (char )* modStr = ! var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
124+ .error(loc, " %s field '%s' initialized multiple times" , modStr, var.toChars());
125+ }
126+ }
127+ else if (sc.noctor || (fi & CSXlabel))
128+ {
129+ if (! mustInit && var.type.isMutable() && e1.type.isMutable())
130+ result = false ;
131+ else
132+ {
133+ const (char )* modStr = ! var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
134+ .error(loc, " %s field '%s' initialization is not allowed in loops or after labels" , modStr, var.toChars());
135+ }
136+ }
137+
138+ sc.fieldinit[i] |= CSXthis_ctor;
139+ if (var.overlapped) // https://issues.dlang.org/show_bug.cgi?id=15258
140+ {
141+ foreach (j, v; ad.fields)
142+ {
143+ if (v is var || ! var.isOverlappedWith(v))
144+ continue ;
145+ v.ctorinit = true ;
146+ sc.fieldinit[j] = CSXthis_ctor;
147+ }
148+ }
149+ }
150+ else if (fd != sc.func)
151+ {
152+ if (var.type.isMutable())
153+ result = false ;
154+ else if (sc.func.fes)
155+ {
156+ const (char )* p = var.isField() ? " field" : var.kind();
157+ .error(loc, " %s %s '%s' initialization is not allowed in foreach loop" ,
158+ MODtoChars(var.type.mod), p, var.toChars());
159+ }
160+ else
161+ {
162+ const (char )* p = var.isField() ? " field" : var.kind();
163+ .error(loc, " %s %s '%s' initialization is not allowed in nested function '%s'" ,
164+ MODtoChars(var.type.mod), p, var.toChars(), sc.func.toChars());
165+ }
166+ }
167+ return result;
168+ }
169+ else
170+ {
171+ if (s)
172+ {
173+ s = s.toParent2();
174+ continue ;
175+ }
176+ }
177+ break ;
178+ }
179+ return false ;
180+ }
181+
75182/* *****************************************
76183 */
77184extern (C++ ) void ObjectNotFound(Identifier id)
0 commit comments