Skip to content

Commit 559252e

Browse files
committed
add -check command line switch
1 parent 7f62a47 commit 559252e

File tree

5 files changed

+92
-10
lines changed

5 files changed

+92
-10
lines changed

changelog/check-switch.dd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Added -check switch to turn on and off each category of runtime checks.
2+
3+
Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
4+
`Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
5+
$(UL
6+
$(LI $(B assert): assertion checking)
7+
$(LI $(B bounds): array bounds)
8+
$(LI $(B in): in contracts)
9+
$(LI $(B invariant): class/struct invariants)
10+
$(LI $(B out): out contracts)
11+
$(LI $(B switch): switch default)
12+
)
13+
$(UL
14+
$(LI $(B on) or not specified: specified check is enabled.)
15+
$(LI $(B off): specified check is disabled.)
16+
)`
17+
)
18+

src/dmd/cli.d

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,30 @@ struct Usage
169169
Option("c",
170170
"compile only, do not link"
171171
),
172+
Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
173+
"Enable or disable specific checks",
174+
`Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
175+
$(UL
176+
$(LI $(B assert): assertion checking)
177+
$(LI $(B bounds): array bounds)
178+
$(LI $(B in): in contracts)
179+
$(LI $(B invariant): class/struct invariants)
180+
$(LI $(B out): out contracts)
181+
$(LI $(B switch): switch default)
182+
)
183+
$(UL
184+
$(LI $(B on) or not specified: specified check is enabled.)
185+
$(LI $(B off): specified check is disabled.)
186+
)`
187+
),
172188
Option("checkaction=D|C|halt",
173189
"behavior on assert/boundscheck/finalswitch failure",
174190
`Sets behavior when an assert fails, and array boundscheck fails,
175191
or a final switch errors.
176192
$(UL
177-
$(LI $(I D): Default behavior, which throws an unrecoverable $(D Error).)
178-
$(LI $(I C): Calls the C runtime library assert failure function.)
179-
$(LI $(I halt): Executes a halt instruction, terminating the program.)
193+
$(LI $(B D): Default behavior, which throws an unrecoverable $(D Error).)
194+
$(LI $(B C): Calls the C runtime library assert failure function.)
195+
$(LI $(B halt): Executes a halt instruction, terminating the program.)
180196
)`
181197
),
182198
Option("color",

src/dmd/globals.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ struct Param
175175
CHECKENABLE useArrayBounds = CHECKENABLE._default; // when to generate code for array bounds checks
176176
CHECKENABLE useAssert = CHECKENABLE._default; // when to generate code for assert()'s
177177
CHECKENABLE useSwitchError = CHECKENABLE._default; // check for switches without a default
178+
CHECKENABLE boundscheck = CHECKENABLE._default; // state of -boundscheck switch
178179

179180
CHECKACTION checkAction = CHECKACTION.D; // action to take when bounds, asserts or switch defaults are violated
180181

src/dmd/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ struct Param
141141
CHECKENABLE useArrayBounds; // when to generate code for array bounds checks
142142
CHECKENABLE useAssert; // when to generate code for assert()'s
143143
CHECKENABLE useSwitchError; // check for switches without a default
144+
CHECKENABLE boundscheck; // state of -boundscheck switch
144145

145146
CHECKACTION checkAction; // action to take when bounds, asserts or switch defaults are violated
146147

src/dmd/mars.d

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,19 @@ private int tryMain(size_t argc, const(char)** argv)
335335
global.params.mscrtlib = vsopt.defaultRuntimeLibrary(global.params.is64bit);
336336
}
337337
}
338+
339+
if (global.params.boundscheck != CHECKENABLE._default)
340+
{
341+
if (global.params.useArrayBounds == CHECKENABLE._default)
342+
global.params.useArrayBounds = global.params.boundscheck;
343+
}
344+
345+
if (global.params.useUnitTests)
346+
{
347+
if (global.params.useAssert == CHECKENABLE._default)
348+
global.params.useAssert = CHECKENABLE.on;
349+
}
350+
338351
if (global.params.release)
339352
{
340353
if (global.params.useInvariants == CHECKENABLE._default)
@@ -376,9 +389,6 @@ private int tryMain(size_t argc, const(char)** argv)
376389
global.params.useSwitchError = CHECKENABLE.on;
377390
}
378391

379-
if (global.params.useUnitTests)
380-
global.params.useAssert = CHECKENABLE.on;
381-
382392
if (global.params.betterC)
383393
{
384394
global.params.checkAction = CHECKACTION.C;
@@ -1499,6 +1509,42 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
14991509
params.useDeprecated = Diagnostic.inform;
15001510
else if (arg == "-c") // https://dlang.org/dmd.html#switch-c
15011511
params.link = false;
1512+
else if (startsWith(p + 1, "check=")) // https://dlang.org/dmd.html#switch-check
1513+
{
1514+
/* Parse:
1515+
* -check=[assert|bounds|in|invariant|out|switch][=[on|off]]
1516+
*/
1517+
1518+
// Check for legal option string; return true if so
1519+
static bool check(const(char)* p, string name, ref CHECKENABLE ce)
1520+
{
1521+
p += "-check=".length;
1522+
if (startsWith(p, name))
1523+
{
1524+
p += name.length;
1525+
if (*p == 0 ||
1526+
strcmp(p, "=on") == 0)
1527+
{
1528+
ce = CHECKENABLE.on;
1529+
return true;
1530+
}
1531+
else if (strcmp(p, "=off") == 0)
1532+
{
1533+
ce = CHECKENABLE.off;
1534+
return true;
1535+
}
1536+
}
1537+
return false;
1538+
}
1539+
1540+
if (!(check(p, "assert", params.useAssert ) ||
1541+
check(p, "bounds", params.useArrayBounds) ||
1542+
check(p, "in", params.useIn ) ||
1543+
check(p, "invariant", params.useInvariants ) ||
1544+
check(p, "out", params.useOut ) ||
1545+
check(p, "switch", params.useSwitchError)))
1546+
goto Lerror;
1547+
}
15021548
else if (startsWith(p + 1, "checkaction=")) // https://dlang.org/dmd.html#switch-checkaction
15031549
{
15041550
/* Parse:
@@ -1956,7 +2002,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
19562002
params.betterC = true;
19572003
else if (arg == "-noboundscheck") // https://dlang.org/dmd.html#switch-noboundscheck
19582004
{
1959-
params.useArrayBounds = CHECKENABLE.off;
2005+
params.boundscheck = CHECKENABLE.off;
19602006
}
19612007
else if (startsWith(p + 1, "boundscheck")) // https://dlang.org/dmd.html#switch-boundscheck
19622008
{
@@ -1966,15 +2012,15 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
19662012
{
19672013
if (strcmp(p + 13, "on") == 0)
19682014
{
1969-
params.useArrayBounds = CHECKENABLE.on;
2015+
params.boundscheck = CHECKENABLE.on;
19702016
}
19712017
else if (strcmp(p + 13, "safeonly") == 0)
19722018
{
1973-
params.useArrayBounds = CHECKENABLE.safeonly;
2019+
params.boundscheck = CHECKENABLE.safeonly;
19742020
}
19752021
else if (strcmp(p + 13, "off") == 0)
19762022
{
1977-
params.useArrayBounds = CHECKENABLE.off;
2023+
params.boundscheck = CHECKENABLE.off;
19782024
}
19792025
else
19802026
goto Lerror;

0 commit comments

Comments
 (0)