Skip to content

Commit

Permalink
Add @saferSystem
Browse files Browse the repository at this point in the history
  • Loading branch information
0xEAB committed Dec 26, 2024
1 parent cf64f24 commit 1d403e5
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 108 deletions.
3 changes: 3 additions & 0 deletions compiler/src/dmd/astbase.d
Original file line number Diff line number Diff line change
Expand Up @@ -3989,6 +3989,8 @@ struct ASTBase
this.trust = TRUST.default_;
if (stc & STC.safe)
this.trust = TRUST.safe;
else if (stc & STC.saferSystem)
this.trust = TRUST.saferSystem;

Check warning on line 3993 in compiler/src/dmd/astbase.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/astbase.d#L3992-L3993

Added lines #L3992 - L3993 were not covered by tests
else if (stc & STC.system)
this.trust = TRUST.system;
else if (stc & STC.trusted)
Expand Down Expand Up @@ -6920,6 +6922,7 @@ struct ASTBase
SCstring(STC.property, "@property"),
SCstring(STC.safe, "@safe"),
SCstring(STC.trusted, "@trusted"),
SCstring(STC.saferSystem, "@saferSystem"),
SCstring(STC.system, "@system"),
SCstring(STC.disable, "@disable"),
SCstring(STC.future, "@__future"),
Expand Down
62 changes: 32 additions & 30 deletions compiler/src/dmd/astenums.d
Original file line number Diff line number Diff line change
Expand Up @@ -96,31 +96,32 @@ enum STC : ulong // transfer changes to declaration.h
gshared = 0x4_0000_0000, /// accessible from multiple threads, but not typed as `shared`
wild = 0x8_0000_0000, /// for wild type constructor

property = 0x10_0000_0000, /// `@property`
safe = 0x20_0000_0000, /// `@safe`
trusted = 0x40_0000_0000, /// `@trusted`
system = 0x80_0000_0000, /// `@system`

ctfe = 0x100_0000_0000, /// can be used in CTFE, even if it is static
disable = 0x200_0000_0000, /// for functions that are not callable
result = 0x400_0000_0000, /// for result variables passed to out contracts
nodefaultctor = 0x800_0000_0000, /// must be set inside constructor

temp = 0x1000_0000_0000, /// temporary variable
rvalue = 0x2000_0000_0000, /// force rvalue for variables
nogc = 0x4000_0000_0000, /// `@nogc`
autoref = 0x8000_0000_0000, /// Mark for the already deduced `auto ref` parameter

inference = 0x1_0000_0000_0000, /// do attribute inference
exptemp = 0x2_0000_0000_0000, /// temporary variable that has lifetime restricted to an expression
future = 0x4_0000_0000_0000, /// introducing new base class function
local = 0x8_0000_0000_0000, /// do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).

live = 0x10_0000_0000_0000, /// function `@live` attribute
register = 0x20_0000_0000_0000, /// `register` storage class (ImportC)
volatile_ = 0x40_0000_0000_0000, /// destined for volatile in the back end

safeGroup = STC.safe | STC.trusted | STC.system,
property = 0x010_0000_0000, /// `@property`
safe = 0x020_0000_0000, /// `@safe`
trusted = 0x040_0000_0000, /// `@trusted`
saferSystem = 0x080_0000_0000, /// `@saferSystem`
system = 0x100_0000_0000, /// `@system`

ctfe = 0x1000_0000_0000, /// can be used in CTFE, even if it is static
disable = 0x2000_0000_0000, /// for functions that are not callable
result = 0x4000_0000_0000, /// for result variables passed to out contracts
nodefaultctor = 0x8000_0000_0000, /// must be set inside constructor

temp = 0x1_0000_0000_0000, /// temporary variable
rvalue = 0x2_0000_0000_0000, /// force rvalue for variables
nogc = 0x4_0000_0000_0000, /// `@nogc`
autoref = 0x8_0000_0000_0000, /// Mark for the already deduced `auto ref` parameter

inference = 0x10_0000_0000_0000, /// do attribute inference
exptemp = 0x20_0000_0000_0000, /// temporary variable that has lifetime restricted to an expression
future = 0x40_0000_0000_0000, /// introducing new base class function
local = 0x80_0000_0000_0000, /// do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).

live = 0x100_0000_0000_0000, /// function `@live` attribute
register = 0x200_0000_0000_0000, /// `register` storage class (ImportC)
volatile_ = 0x400_0000_0000_0000, /// destined for volatile in the back end

safeGroup = STC.safe | STC.trusted | STC.saferSystem | STC.system,
IOR = STC.constscoperef | STC.in_ | STC.ref_ | STC.out_,
TYPECTOR = (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild),
FUNCATTR = (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.property | STC.live |
Expand All @@ -139,7 +140,7 @@ enum STC : ulong // transfer changes to declaration.h
flowThruAggregate = STC.safeGroup, /// for an AggregateDeclaration
flowThruFunction = ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.abstract_ | STC.deprecated_ | STC.override_ |
STC.TYPECTOR | STC.final_ | STC.tls | STC.gshared | STC.ref_ | STC.return_ | STC.property |
STC.nothrow_ | STC.pure_ | STC.safe | STC.trusted | STC.system), /// for a FuncDeclaration
STC.nothrow_ | STC.pure_ | STC.safe | STC.trusted | STC.saferSystem | STC.system), /// for a FuncDeclaration

}

Expand Down Expand Up @@ -301,10 +302,11 @@ enum ThreeState : ubyte

enum TRUST : ubyte
{
default_ = 0,
system = 1, // @system (same as TRUST.default)
trusted = 2, // @trusted
safe = 3, // @safe
default_ = 0,
system = 1, // @system (same as TRUST.default_ unless feature "safer" is enabled)
saferSystem = 2, // @saferSystem (same as TRUST.default_ if feature "safer" is enabled)
trusted = 3, // @trusted
safe = 4, // @safe
}

enum PURE : ubyte
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/clone.d
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ StorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure @safe
auto tf = f.type.isTypeFunction();
if (tf.trust == TRUST.safe)
s2 |= STC.safe;
else if (tf.trust == TRUST.saferSystem)
s2 |= STC.system;

Check warning on line 64 in compiler/src/dmd/clone.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/clone.d#L64

Added line #L64 was not covered by tests
else if (tf.trust == TRUST.system)
s2 |= STC.system;
else if (tf.trust == TRUST.trusted)
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2301,8 +2301,11 @@ private bool checkSafety(FuncDeclaration f, ref Loc loc, Scope* sc)
if (!loc.isValid()) // e.g. implicitly generated dtor
loc = sc.func.loc;

immutable msg = (f.isSaferD())
? "`@safe` %s `%s` cannot call `@saferSystem` %s `%s`"

Check warning on line 2305 in compiler/src/dmd/expressionsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expressionsem.d#L2305

Added line #L2305 was not covered by tests
: "`@safe` %s `%s` cannot call `@system` %s `%s`";
const prettyChars = f.toPrettyChars();
error(loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
error(loc, msg.ptr,
sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
prettyChars);
if (!f.isDtorDeclaration)
Expand Down
123 changes: 62 additions & 61 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -5306,67 +5306,68 @@ enum class MODFlags

enum class STC : uint64_t
{
undefined_ = 0LLU,
static_ = 1LLU,
extern_ = 2LLU,
const_ = 4LLU,
final_ = 8LLU,
abstract_ = 16LLU,
parameter = 32LLU,
field = 64LLU,
override_ = 128LLU,
auto_ = 256LLU,
synchronized_ = 512LLU,
deprecated_ = 1024LLU,
in_ = 2048LLU,
out_ = 4096LLU,
lazy_ = 8192LLU,
foreach_ = 16384LLU,
variadic = 32768LLU,
constscoperef = 65536LLU,
templateparameter = 131072LLU,
ref_ = 262144LLU,
scope_ = 524288LLU,
scopeinferred = 2097152LLU,
return_ = 4194304LLU,
returnScope = 8388608LLU,
returninferred = 16777216LLU,
immutable_ = 33554432LLU,
manifest = 134217728LLU,
nodtor = 268435456LLU,
nothrow_ = 536870912LLU,
pure_ = 1073741824LLU,
tls = 2147483648LLU,
alias_ = 4294967296LLU,
shared_ = 8589934592LLU,
gshared = 17179869184LLU,
wild = 34359738368LLU,
property = 68719476736LLU,
safe = 137438953472LLU,
trusted = 274877906944LLU,
system = 549755813888LLU,
ctfe = 1099511627776LLU,
disable = 2199023255552LLU,
result = 4398046511104LLU,
nodefaultctor = 8796093022208LLU,
temp = 17592186044416LLU,
rvalue = 35184372088832LLU,
nogc = 70368744177664LLU,
autoref = 140737488355328LLU,
inference = 281474976710656LLU,
exptemp = 562949953421312LLU,
future = 1125899906842624LLU,
local = 2251799813685248LLU,
live = 4503599627370496LLU,
register_ = 9007199254740992LLU,
volatile_ = 18014398509481984LLU,
safeGroup = 962072674304LLU,
IOR = 333824LLU,
TYPECTOR = 42983227396LLU,
FUNCATTR = 4575000774574080LLU,
visibleStorageClasses = 7954966262857631LLU,
flowThruAggregate = 962072674304LLU,
flowThruFunction = 18446742978991225440LLU,
undefined_ = 0LLU
static_ = 1LLU
extern_ = 2LLU
const_ = 4LLU
final_ = 8LLU
abstract_ = 16LLU
parameter = 32LLU
field = 64LLU
override_ = 128LLU
auto_ = 256LLU
synchronized_ = 512LLU
deprecated_ = 1024LLU
in_ = 2048LLU
out_ = 4096LLU
lazy_ = 8192LLU
foreach_ = 16384LLU
variadic = 32768LLU
constscoperef = 65536LLU
templateparameter = 131072LLU
ref_ = 262144LLU
scope_ = 524288LLU
scopeinferred = 2097152LLU
return_ = 4194304LLU
returnScope = 8388608LLU
returninferred = 16777216LLU
immutable_ = 33554432LLU
manifest = 134217728LLU
nodtor = 268435456LLU
nothrow_ = 536870912LLU
pure_ = 1073741824LLU
tls = 2147483648LLU
alias_ = 4294967296LLU
shared_ = 8589934592LLU
gshared = 17179869184LLU
wild = 34359738368LLU
property = 68719476736LLU
safe = 137438953472LLU
trusted = 274877906944LLU
saferSystem = 549755813888LLU
system = 1099511627776LLU
ctfe = 17592186044416LLU
disable = 35184372088832LLU
result = 70368744177664LLU
nodefaultctor = 140737488355328LLU
temp = 281474976710656LLU
rvalue = 562949953421312LLU
nogc = 1125899906842624LLU
autoref = 2251799813685248LLU
inference = 4503599627370496LLU
exptemp = 9007199254740992LLU
future = 18014398509481984LLU
local = 36028797018963968LLU
live = 72057594037927936LLU
register_ = 144115188075855872LLU
volatile_ = 288230376151711744LLU
safeGroup = 2061584302080LLU
IOR = 333824LLU
TYPECTOR = 42983227396LLU
FUNCATTR = 73185625859424256LLU
visibleStorageClasses = 127264072504459167LLU
flowThruAggregate = 2061584302080LLU
flowThruFunction = 18446741879479597664LLU
};

struct ASTCodegen final
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/funcsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
sc.stc &= ~STC.safeGroup;
if (tf.trust == TRUST.safe)
sc.stc |= STC.safe;
else if (tf.trust == TRUST.saferSystem)
sc.stc |= STC.saferSystem;

Check warning on line 377 in compiler/src/dmd/funcsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/funcsem.d#L377

Added line #L377 was not covered by tests
else if (tf.trust == TRUST.system)
sc.stc |= STC.system;
else if (tf.trust == TRUST.trusted)
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/hdrgen.d
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,7 @@ string stcToString(ref StorageClass stc) @safe
SCstring(STC.property, "@property"),
SCstring(STC.safe, "@safe"),
SCstring(STC.trusted, "@trusted"),
SCstring(STC.saferSystem, "@saferSystem"),
SCstring(STC.system, "@system"),
SCstring(STC.disable, "@disable"),
SCstring(STC.future, "@__future"),
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/id.d
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ immutable Msgtable[] msgtable =
{ "nogc" },
{ "live" },
{ "safe" },
{ "saferSystem" },
{ "trusted" },
{ "system" },
{ "disable" },
Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dmd/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,10 @@ public:
// Should not be printed
//property(name, "default");
break;
case TRUST.system: return property(name, "system");
case TRUST.trusted: return property(name, "trusted");
case TRUST.safe: return property(name, "safe");
case TRUST.system: return property(name, "system");
case TRUST.saferSystem: return property(name, "saferSystem");
case TRUST.trusted: return property(name, "trusted");
case TRUST.safe: return property(name, "safe");

Check warning on line 296 in compiler/src/dmd/json.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/json.d#L293-L296

Added lines #L293 - L296 were not covered by tests
}
}

Expand Down
5 changes: 5 additions & 0 deletions compiler/src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ string trustToString(TRUST trust) pure nothrow @nogc @safe
return null;
case TRUST.system:
return "@system";
case TRUST.saferSystem:
return "@saferSystem";
case TRUST.trusted:
return "@trusted";
case TRUST.safe:
Expand All @@ -225,6 +227,7 @@ unittest
{
assert(trustToString(TRUST.default_) == "");
assert(trustToString(TRUST.system) == "@system");
assert(trustToString(TRUST.saferSystem) == "@saferSystem");
assert(trustToString(TRUST.trusted) == "@trusted");
assert(trustToString(TRUST.safe) == "@safe");
}
Expand Down Expand Up @@ -2538,6 +2541,8 @@ extern (C++) final class TypeFunction : TypeNext
this.trust = TRUST.default_;
if (stc & STC.safe)
this.trust = TRUST.safe;
else if (stc & STC.saferSystem)
this.trust = TRUST.saferSystem;

Check warning on line 2545 in compiler/src/dmd/mtype.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/mtype.d#L2545

Added line #L2545 was not covered by tests
else if (stc & STC.system)
this.trust = TRUST.system;
else if (stc & STC.trusted)
Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dmd/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,10 @@ enum RET
enum class TRUST : unsigned char
{
default_ = 0,
system = 1, // @system (same as TRUSTdefault)
trusted = 2, // @trusted
safe = 3 // @safe
system = 1, // @system (same as TRUST.default_ unless feature "safer" is enabled)
saferSystem = 2, // @saferSystem (same as TRUST.default_ if feature "safer" is enabled)
trusted = 3, // @trusted
safe = 4 // @safe
};

enum TRUSTformat
Expand Down
17 changes: 9 additions & 8 deletions compiler/src/dmd/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -9636,14 +9636,15 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
*/
static StorageClass isBuiltinAtAttribute(Identifier ident)
{
return (ident == Id.property) ? STC.property :
(ident == Id.nogc) ? STC.nogc :
(ident == Id.safe) ? STC.safe :
(ident == Id.trusted) ? STC.trusted :
(ident == Id.system) ? STC.system :
(ident == Id.live) ? STC.live :
(ident == Id.future) ? STC.future :
(ident == Id.disable) ? STC.disable :
return (ident == Id.property) ? STC.property :
(ident == Id.nogc) ? STC.nogc :
(ident == Id.safe) ? STC.safe :
(ident == Id.saferSystem) ? STC.saferSystem :
(ident == Id.trusted) ? STC.trusted :
(ident == Id.system) ? STC.system :
(ident == Id.live) ? STC.live :
(ident == Id.future) ? STC.future :
(ident == Id.disable) ? STC.disable :
0;
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dmd/safe.d
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ bool checkUnsafeDotExp(Scope* sc, Expression e, Identifier id, int flag)
*/
bool isSaferD(FuncDeclaration fd)
{
return fd.type.toTypeFunction().trust == TRUST.default_ &&
global.params.safer == FeatureState.enabled;
return fd.type.toTypeFunction().trust == TRUST.saferSystem ||
(fd.type.toTypeFunction().trust == TRUST.default_ &&
global.params.safer == FeatureState.enabled);
}

bool isSafe(FuncDeclaration fd)
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2234,6 +2234,8 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
{
if (sc.stc & STC.safe)
tf.trust = TRUST.safe;
else if (sc.stc & STC.saferSystem)
tf.trust = TRUST.saferSystem;

Check warning on line 2238 in compiler/src/dmd/typesem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/typesem.d#L2238

Added line #L2238 was not covered by tests
else if (sc.stc & STC.system)
tf.trust = TRUST.system;
else if (sc.stc & STC.trusted)
Expand Down
18 changes: 18 additions & 0 deletions compiler/test/fail_compilation/safer_attrib.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
TEST_OUTPUT:
---
fail_compilation/safer_attrib.d(10): Error: `void` initializers for pointers not allowed in safe functions
---
*/

void test1() @saferSystem
{
int* p = void;
}

void foo3() { }

void test2()
{
foo3(); // should not be an error
}
Loading

0 comments on commit 1d403e5

Please sign in to comment.