Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move isSafe/setUnsafe to safe.d #16871

Merged
merged 1 commit into from
Oct 5, 2024
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
1 change: 1 addition & 0 deletions compiler/src/dmd/dcast.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import dmd.root.ctfloat;
import dmd.common.outbuffer;
import dmd.root.rmem;
import dmd.root.utf;
import dmd.safe : setUnsafe;
import dmd.tokens;
import dmd.typesem;

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
import dmd.rootobject;
import dmd.safe;
import dmd.semantic2;
import dmd.semantic3;
import dmd.sideeffect;
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/escape.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import dmd.location;
import dmd.mtype;
import dmd.printast;
import dmd.rootobject;
import dmd.safe;
import dmd.tokens;
import dmd.typesem : hasPointers, parameterStorageClass;
import dmd.visitor;
Expand Down
2 changes: 0 additions & 2 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -3773,8 +3773,6 @@ class FuncDeclaration : public Declaration
bool isCodeseg() const final override;
bool isOverloadable() const final override;
bool isAbstract() final override;
bool isSafe();
bool isTrusted();
virtual bool isNested() const;
AggregateDeclaration* isThis() override;
bool needThis() final override;
Expand Down
66 changes: 0 additions & 66 deletions compiler/src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -685,72 +685,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);
}

/**************************************
* The function is doing something that may throw an exception, register that in case nothrow is being inferred
Expand Down
111 changes: 1 addition & 110 deletions compiler/src/dmd/funcsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import dmd.rootobject;
import dmd.root.filename;
import dmd.root.string;
import dmd.root.stringtable;
import dmd.safe;
import dmd.semantic2;
import dmd.semantic3;
import dmd.statement;
Expand Down Expand Up @@ -2807,116 +2808,6 @@ bool isRootTraitsCompilesScope(Scope* sc) @safe
return (sc.traitsCompiles) && !sc.func.skipCodegen;
}

/**************************************
* A statement / expression in this scope is not `@safe`,
* so mark the enclosing function as `@system`
*
* Params:
* sc = scope that the unsafe statement / expression is in
* 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
*/
bool setUnsafe(Scope* sc,
bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
if (sc.intypeof)
return false; // typeof(cast(int*)0) is safe

if (sc.debug_) // debug {} scopes are permissive
return false;

if (!sc.func)
{
if (sc.varDecl)
{
if (sc.varDecl.storage_class & STC.safe)
{
.error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
return true;
}
else if (!(sc.varDecl.storage_class & STC.trusted))
{
sc.varDecl.storage_class |= STC.system;
sc.varDecl.systemInferred = true;
}
}
return false;
}


if (isRootTraitsCompilesScope(sc)) // __traits(compiles, x)
{
if (sc.func.isSafeBypassingInference())
{
// Message wil be gagged, but still call error() to update global.errors and for
// -verrors=spec
.error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
return true;
}
return false;
}

return sc.func.setUnsafe(gag, loc, fmt, arg0, arg1, arg2);
}

/***************************************
* Like `setUnsafe`, but for safety errors still behind preview switches
*
* Given a `FeatureState fs`, for example dip1000 / dip25 / systemVariables,
* the behavior changes based on the setting:
*
* - In case of `-revert=fs`, it does nothing.
* - In case of `-preview=fs`, it's the same as `setUnsafe`
* - By default, print a deprecation in `@safe` functions, or store an attribute violation in inferred functions.
*
* Params:
* sc = used to find affected function/variable, and for checking whether we are in a deprecated / speculative scope
* fs = feature state from the preview flag
* gag = surpress error message
* loc = location of error
* msg = 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 an actual safe error (not deprecation) occured
*/
bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
//printf("setUnsafePreview() fs:%d %s\n", fs, msg);
with (FeatureState) final switch (fs)
{
case disabled:
return false;

case enabled:
return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2);

case default_:
if (!sc.func)
return false;
if (sc.func.isSafeBypassingInference())
{
if (!gag && !sc.isDeprecated())
{
deprecation(loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
}
}
else if (!sc.func.safetyViolation)
{
import dmd.func : AttributeViolation;
sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2);
}
return false;
}
}

/+
+ Checks the parameter and return types iff this is a `main` function.
+
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/initsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import dmd.location;
import dmd.mtype;
import dmd.opover;
import dmd.optimize;
import dmd.safe : setUnsafe;
import dmd.statement;
import dmd.target;
import dmd.tokens;
Expand Down
Loading
Loading