Skip to content

Commit

Permalink
refactor: merge redundate super() and this() code
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Apr 4, 2018
1 parent 44d849e commit 8febede
Showing 1 changed file with 33 additions and 12 deletions.
45 changes: 33 additions & 12 deletions src/dmd/expressionsem.d
Expand Up @@ -3249,23 +3249,35 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
t1 = exp.e1.type;
}
else if (exp.e1.op == TOK.super_)
else if (exp.e1.op == TOK.super_ /*|| exp.e1.op == TOK.this_*/)
{
// Base class constructor call
auto ad = sc.func ? sc.func.isThis() : null;
auto cd = ad ? ad.isClassDeclaration() : null;
if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())

if (exp.e1.op == TOK.super_)
{
exp.error("super class constructor call must be in a constructor");
return setError();
// Base class constructor call
if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())
{
exp.error("super class constructor call must be in a constructor");
return setError();
}
if (!cd.baseClass.ctor)
{
exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
return setError();
}
}
if (!cd.baseClass.ctor)
else
{
exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
return setError();
if (!ad || !sc.func.isCtorDeclaration())
{
exp.error("constructor call must be in a constructor");
return setError();
}
}

if (!sc.intypeof)
if (!sc.intypeof /*&& !(sc.ctorflow.callSuper & CSX.halt)*/)
{
if (sc.noctor || sc.ctorflow.callSuper & CSX.label)
exp.error("constructor calls not allowed in loops or after labels");
Expand All @@ -3276,11 +3288,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
sc.ctorflow.callSuper |= CSX.any_ctor | CSX.super_ctor;
}

tthis = cd.type.addMod(sc.func.type.mod);
if (auto os = cd.baseClass.ctor.isOverloadSet())
tthis = ad.type.addMod(sc.func.type.mod);
auto ctor = (exp.e1.op == TOK.super_) ? cd.baseClass.ctor : ad.ctor;
if (auto os = ctor.isOverloadSet())
exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);
else
exp.f = resolveFuncCall(exp.loc, sc, cd.baseClass.ctor, null, tthis, exp.arguments, 0);
exp.f = resolveFuncCall(exp.loc, sc, ctor, null, tthis, exp.arguments, 0);

if (!exp.f || exp.f.errors)
return setError();
Expand All @@ -3291,6 +3304,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);
exp.e1 = exp.e1.expressionSemantic(sc);
t1 = exp.e1.type;

// BUG: this should really be done by checking the static
// call graph
if (exp.f == sc.func)
{
exp.error("cyclic constructor call");
return setError();
}
}
else if (exp.e1.op == TOK.this_)
{
Expand Down

0 comments on commit 8febede

Please sign in to comment.