Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions src/ddmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,113 @@ extern (C++) bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad,
return result;
}

/***********************************************
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't you mean to move modifyFieldVar to src/ddmd/expressionsem.d?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, the function is called just once from declaration.d. Don't know why it was in expression.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the pull-request commit by commit and I noticed that the commit message of this change was "Move mofifyFieldVar to expressionsem and make it private", so it would be better to change the commit message to "Move mofifyFieldVar to declaration and make it private", in order to avoid confusion.

* Mark variable v as modified if it is inside a constructor that var
* is a field in.
*/
private int modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
{
//printf("modifyFieldVar(var = %s)\n", var.toChars());
Dsymbol s = sc.func;
while (1)
{
FuncDeclaration fd = null;
if (s)
fd = s.isFuncDeclaration();
if (fd &&
((fd.isCtorDeclaration() && var.isField()) ||
(fd.isStaticCtorDeclaration() && !var.isField())) &&
fd.toParent2() == var.toParent2() &&
(!e1 || e1.op == TOKthis))
{
bool result = true;

var.ctorinit = true;
//printf("setting ctorinit\n");

if (var.isField() && sc.fieldinit && !sc.intypeof)
{
assert(e1);
auto mustInit = ((var.storage_class & STCnodefaultctor) != 0 ||
var.type.needsNested());

auto dim = sc.fieldinit_dim;
auto ad = fd.isMember2();
assert(ad);
size_t i;
for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ?
{
if (ad.fields[i] == var)
break;
}
assert(i < dim);
uint fi = sc.fieldinit[i];

if (fi & CSXthis_ctor)
{
if (var.type.isMutable() && e1.type.isMutable())
result = false;
else
{
const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
.error(loc, "%s field '%s' initialized multiple times", modStr, var.toChars());
}
}
else if (sc.noctor || (fi & CSXlabel))
{
if (!mustInit && var.type.isMutable() && e1.type.isMutable())
result = false;
else
{
const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
.error(loc, "%s field '%s' initialization is not allowed in loops or after labels", modStr, var.toChars());
}
}

sc.fieldinit[i] |= CSXthis_ctor;
if (var.overlapped) // https://issues.dlang.org/show_bug.cgi?id=15258
{
foreach (j, v; ad.fields)
{
if (v is var || !var.isOverlappedWith(v))
continue;
v.ctorinit = true;
sc.fieldinit[j] = CSXthis_ctor;
}
}
}
else if (fd != sc.func)
{
if (var.type.isMutable())
result = false;
else if (sc.func.fes)
{
const(char)* p = var.isField() ? "field" : var.kind();
.error(loc, "%s %s '%s' initialization is not allowed in foreach loop",
MODtoChars(var.type.mod), p, var.toChars());
}
else
{
const(char)* p = var.isField() ? "field" : var.kind();
.error(loc, "%s %s '%s' initialization is not allowed in nested function '%s'",
MODtoChars(var.type.mod), p, var.toChars(), sc.func.toChars());
}
}
return result;
}
else
{
if (s)
{
s = s.toParent2();
continue;
}
}
break;
}
return false;
}

/******************************************
*/
extern (C++) void ObjectNotFound(Identifier id)
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/dstruct.d
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import ddmd.dsymbolsem;
import ddmd.dtemplate;
import ddmd.errors;
import ddmd.expression;
import ddmd.expressionsem;
import ddmd.func;
import ddmd.globals;
import ddmd.id;
Expand Down
Loading