Skip to content

Commit ba85bbd

Browse files
committed
check nogc on default func args but do not check nogc in if(__ctfe) blocks
1 parent 9adbc04 commit ba85bbd

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

compiler/src/dmd/expression.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ extern (C++) /* IN_LLVM abstract */ class Expression : ASTNode
348348
Loc loc; // file location
349349
const EXP op; // to minimize use of dynamic_cast
350350

351+
bool ctfe = false; // TODO: bake this byte flag or move to relevant Expressions
352+
351353
extern (D) this(const ref Loc loc, EXP op) scope @safe
352354
{
353355
//printf("Expression::Expression(op = %d) this = %p\n", op, this);

compiler/src/dmd/expressionsem.d

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2899,9 +2899,27 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
28992899
arg = p.defaultArg;
29002900
if (!arg.type)
29012901
arg = arg.expressionSemantic(sc);
2902+
2903+
if (auto efd = sc.getEnclosingFunction()) {
2904+
TypeFunction etf = efd.type.toTypeFunction();
2905+
if (etf && etf.isnogc) {
2906+
if (auto ce = arg.isCallExp()) {
2907+
if (TypeFunction atf = ce.f.type.toTypeFunction()) {
2908+
// Both conditions works
2909+
if (!atf.isnogc) {
2910+
// if (!ce.f.setGC(arg.loc, "`@nogc` %s `%s` cannot call non-@nogc")) {
2911+
error(loc, "`@nogc` `%s` cannot call `%s` with non-@nogc argument `%s`", efd.toChars(), tf.toChars(), arg.toChars());
2912+
return true;
2913+
}
2914+
}
2915+
}
2916+
}
2917+
}
2918+
29022919
arg = inlineCopy(arg, sc);
29032920
// __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__
29042921
arg = arg.resolveLoc(loc, sc);
2922+
29052923
if (i >= nargs)
29062924
{
29072925
arguments.push(arg);
@@ -14190,7 +14208,13 @@ extern (C++) Expression expressionSemantic(Expression e, Scope* sc)
1419014208
{
1419114209
scope v = new ExpressionSemanticVisitor(sc);
1419214210
e.accept(v);
14193-
return v.result;
14211+
14212+
auto res = v.result;
14213+
14214+
if(sc && (sc.flags & SCOPE.ctfeBlock))
14215+
e.ctfe = true;
14216+
14217+
return res;
1419414218
}
1419514219

1419614220
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)

compiler/src/dmd/nogc.d

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public:
150150
if (global.params.ehnogc && e.thrownew)
151151
return; // separate allocator is called for this, not the GC
152152
if (explicit_gc)
153-
return; // `new` is an explicit allocation
153+
return; // `new` is an explicit allocation
154154
if (setGC(e, "cannot use `new` in `@nogc` %s `%s`"))
155155
return;
156156
f.printGCUsage(e.loc, "`new` causes a GC allocation");
@@ -219,6 +219,9 @@ Expression checkGC(Scope* sc, Expression e)
219219
if (sc.flags & SCOPE.ctfeBlock) // ignore GC in ctfe blocks
220220
return e;
221221

222+
if (e.ctfe)
223+
return e;
224+
222225
/* If betterC, allow GC to happen in non-CTFE code.
223226
* Just don't generate code for it.
224227
* Detect non-CTFE use of the GC in betterC code.

0 commit comments

Comments
 (0)