Skip to content

Commit

Permalink
move isSafe/setUnsafe to safe.d
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator committed Sep 23, 2024
1 parent ec6dcca commit 87047b4
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 66 deletions.
66 changes: 0 additions & 66 deletions compiler/src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -708,72 +708,6 @@ extern (C++) class FuncDeclaration : Declaration
return bitFields;
}

final bool isSafe()
{
if (safetyInprocess)
setUnsafe();
return type.toTypeFunction().trust == TRUST.safe;
}

extern (D) final bool isSafeBypassingInference()
{
return !(safetyInprocess) && isSafe();
}

final bool isTrusted()
{
if (safetyInprocess)
setUnsafe();
return type.toTypeFunction().trust == TRUST.trusted;
}

/**************************************
* The function is doing something unsafe, so mark it as unsafe.
*
* Params:
* gag = surpress error message (used in escape.d)
* loc = location of error
* fmt = printf-style format string
* arg0 = (optional) argument for first %s format specifier
* arg1 = (optional) argument for second %s format specifier
* arg2 = (optional) argument for third %s format specifier
* Returns: whether there's a safe error
*/
extern (D) final bool setUnsafe(
bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
if (safetyInprocess)
{
safetyInprocess = false;
type.toTypeFunction().trust = TRUST.system;
if (fmt || arg0)
safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1, arg2);

if (fes)
fes.func.setUnsafe();
}
else if (isSafe())
{
if (!gag && fmt)
.error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");

return true;
}
return false;
}

/**************************************
* The function is calling `@system` function `f`, so mark it as unsafe.
*
* Params:
* f = function being called (needed for diagnostic of inferred functions)
* Returns: whether there's a safe error
*/
extern (D) final bool setUnsafeCall(FuncDeclaration f)
{
return setUnsafe(false, f.loc, null, f, null);
}

final bool isNogc()
{
Expand Down
72 changes: 72 additions & 0 deletions compiler/src/dmd/safe.d
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ import dmd.dclass;
import dmd.declaration;
import dmd.dscope;
import dmd.expression;
import dmd.func;
import dmd.id;
import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.root.rootobject;
import dmd.target;
import dmd.tokens;
import dmd.typesem : hasPointers, arrayOf, size;
Expand Down Expand Up @@ -309,3 +312,72 @@ bool checkUnsafeDotExp(Scope* sc, Expression e, Identifier id, int flag)
}
return false;
}

bool isSafe(FuncDeclaration fd)
{
if (fd.safetyInprocess)
fd.setUnsafe();
return fd.type.toTypeFunction().trust == TRUST.safe;
}

extern (D) bool isSafeBypassingInference(FuncDeclaration fd)
{
return !(fd,safetyInprocess) && fd.isSafe();
}

bool isTrusted(FuncDeclaration fd)
{
if (fd.safetyInprocess)
fd.setUnsafe();
return fd.type.toTypeFunction().trust == TRUST.trusted;
}

/**************************************
* The function is doing something unsafe, so mark it as unsafe.
*
* Params:
* gag = surpress error message (used in escape.d)
* loc = location of error
* fmt = printf-style format string
* arg0 = (optional) argument for first %s format specifier
* arg1 = (optional) argument for second %s format specifier
* arg2 = (optional) argument for third %s format specifier
* Returns: whether there's a safe error
*/
extern (D) bool setUnsafe(
FuncDeclaration fd,
bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
if (fd.safetyInprocess)
{
fd.safetyInprocess = false;
fd.type.toTypeFunction().trust = TRUST.system;
if (fmt || arg0)
fd.safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1, arg2);

if (fd.fes)
fd.fes.func.setUnsafe();
}
else if (fd.isSafe())
{
if (!gag && fmt)
.error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");

return true;
}
return false;
}

/**************************************
* The function is calling `@system` function `f`, so mark it as unsafe.
*
* Params:
* fd = caller
* f = function being called (needed for diagnostic of inferred functions)
* Returns: whether there's a safe error
*/
extern (D) bool setUnsafeCall(FuncDeclaration fd, FuncDeclaration f)
{
return fd.setUnsafe(false, f.loc, null, f, null);
}

0 comments on commit 87047b4

Please sign in to comment.