Skip to content

Commit

Permalink
move setGC[Call] to nogc.d (dlang#16870)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator authored Sep 23, 2024
1 parent 079e695 commit 6f1b331
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 66 deletions.
1 change: 0 additions & 1 deletion compiler/src/dmd/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,6 @@ class FuncDeclaration : public Declaration
bool isAbstract() override final;
bool isSafe();
bool isTrusted();
bool isNogc();

virtual bool isNested() const;
AggregateDeclaration *isThis() override;
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import dmd.location;
import dmd.mtype;
import dmd.mustuse;
import dmd.nspace;
import dmd.nogc;
import dmd.objc;
import dmd.opover;
import dmd.optimize;
Expand Down
1 change: 0 additions & 1 deletion compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -3790,7 +3790,6 @@ class FuncDeclaration : public Declaration
bool isAbstract() final override;
bool isSafe();
bool isTrusted();
bool isNogc();
virtual bool isNested() const;
AggregateDeclaration* isThis() override;
bool needThis() final override;
Expand Down
63 changes: 0 additions & 63 deletions compiler/src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -754,69 +754,6 @@ extern (C++) class FuncDeclaration : Declaration
return setUnsafe(false, f.loc, null, f, null);
}

final bool isNogc()
{
//printf("isNogc() %s, inprocess: %d\n", toChars(), !!(flags & FUNCFLAG.nogcInprocess));
if (nogcInprocess)
setGC(loc, null);
return type.toTypeFunction().isNogc;
}

extern (D) final bool isNogcBypassingInference()
{
return !nogcInprocess && isNogc();
}

/**************************************
* The function is doing something that may allocate with the GC,
* so mark it as not nogc (not no-how).
*
* Params:
* loc = location of impure action
* fmt = format string for error message. Must include "%s `%s`" for the function kind and name.
* arg0 = (optional) argument to format string
*
* Returns:
* true if function is marked as @nogc, meaning a user error occurred
*/
extern (D) final bool setGC(Loc loc, const(char)* fmt, RootObject arg0 = null)
{
//printf("setGC() %s\n", toChars());
if (nogcInprocess && semanticRun < PASS.semantic3 && _scope)
{
this.semantic2(_scope);
this.semantic3(_scope);
}

if (nogcInprocess)
{
nogcInprocess = false;
if (fmt)
nogcViolation = new AttributeViolation(loc, fmt, this, arg0); // action that requires GC
else if (arg0)
nogcViolation = new AttributeViolation(loc, fmt, arg0); // call to non-@nogc function

type.toTypeFunction().isNogc = false;
if (fes)
fes.func.setGC(Loc.init, null, null);
}
else if (isNogc())
return true;
return false;
}

/**************************************
* The function calls non-`@nogc` function f, mark it as not nogc.
* Params:
* f = function being called
* Returns:
* true if function is marked as @nogc, meaning a user error occurred
*/
extern (D) final bool setGCCall(FuncDeclaration f)
{
return setGC(loc, null, f);
}

/**************************************
* The function is doing something that may throw an exception, register that in case nothrow is being inferred
*
Expand Down
70 changes: 69 additions & 1 deletion compiler/src/dmd/nogc.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import dmd.declaration;
import dmd.dmodule;
import dmd.dscope;
import dmd.dtemplate : isDsymbol;
import dmd.dsymbol : PASS;
import dmd.errors;
import dmd.expression;
import dmd.func;
Expand All @@ -29,6 +30,9 @@ import dmd.init;
import dmd.location;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.rootobject : RootObject, DYNCAST;
import dmd.semantic2;
import dmd.semantic3;
import dmd.tokens;
import dmd.visitor;

Expand Down Expand Up @@ -258,7 +262,6 @@ private FuncDeclaration stripHookTraceImpl(FuncDeclaration fd)
{
import dmd.id : Id;
import dmd.dsymbol : Dsymbol;
import dmd.rootobject : RootObject, DYNCAST;

if (fd.ident != Id._d_HookTraceImpl)
return fd;
Expand All @@ -270,3 +273,68 @@ private FuncDeclaration stripHookTraceImpl(FuncDeclaration fd)
assert(s, "Expected _d_HookTraceImpl's second template parameter to be an alias to the hook!");
return s.isFuncDeclaration;
}

/**************************************
* The function is doing something that may allocate with the GC,
* so mark it as not nogc (not no-how).
*
* Params:
* fd = function
* loc = location of GC action
* fmt = format string for error message. Must include "%s `%s`" for the function kind and name.
* arg0 = (optional) argument to format string
*
* Returns:
* true if function is marked as @nogc, meaning a user error occurred
*/
extern (D) bool setGC(FuncDeclaration fd, Loc loc, const(char)* fmt, RootObject arg0 = null)
{
//printf("setGC() %s\n", toChars());
if (fd.nogcInprocess && fd.semanticRun < PASS.semantic3 && fd._scope)
{
fd.semantic2(fd._scope);
fd.semantic3(fd._scope);
}

if (fd.nogcInprocess)
{
fd.nogcInprocess = false;
if (fmt)
fd.nogcViolation = new AttributeViolation(loc, fmt, fd, arg0); // action that requires GC
else if (arg0)
fd.nogcViolation = new AttributeViolation(loc, fmt, arg0); // call to non-@nogc function

fd.type.toTypeFunction().isNogc = false;
if (fd.fes)
fd.fes.func.setGC(Loc.init, null, null);
}
else if (fd.isNogc())
return true;
return false;
}

/**************************************
* The function calls non-`@nogc` function f, mark it as not nogc.
* Params:
* fd = function doin the call
* f = function being called
* Returns:
* true if function is marked as @nogc, meaning a user error occurred
*/
extern (D) bool setGCCall(FuncDeclaration fd, FuncDeclaration f)
{
return fd.setGC(fd.loc, null, f);
}

bool isNogc(FuncDeclaration fd)
{
//printf("isNogc() %s, inprocess: %d\n", toChars(), !!(flags & FUNCFLAG.nogcInprocess));
if (fd.nogcInprocess)
fd.setGC(fd.loc, null);
return fd.type.toTypeFunction().isNogc;
}

extern (D) bool isNogcBypassingInference(FuncDeclaration fd)
{
return !fd.nogcInprocess && fd.isNogc();
}
1 change: 1 addition & 0 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import dmd.initsem;
import dmd.location;
import dmd.visitor;
import dmd.mtype;
import dmd.nogc;
import dmd.objc;
import dmd.opover;
import dmd.optimize;
Expand Down

0 comments on commit 6f1b331

Please sign in to comment.