d: Merge upstream dmd f5638c7b8.
Adds a CHECKENABLE enum, uses it for all contract parameters for consistency in state checking. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd f5638c7b8. * d-builtins.cc (d_init_versions): Use new CHECKENABLE enum. * d-codegen.cc (array_bounds_check): Likewise. (build_frame_type): Likewise. (get_frameinfo): Likewise. * d-lang.cc (d_init_options): Likewise. (d_init_options_struct): Don't initialize x_flag_bounds_check. (d_handle_option): Use new CHECKENABLE enum. (d_post_options): Likewise. Set flag_bounds_check here. * expr.cc (ExprVisitor::visit(AssertExp *)): Use new CHECKENABLE enum.
This commit is contained in:
parent
5094c4400a
commit
0cdc55f5ed
|
@ -472,10 +472,10 @@ d_init_versions (void)
|
|||
if (global.params.useUnitTests)
|
||||
VersionCondition::addPredefinedGlobalIdent ("unittest");
|
||||
|
||||
if (global.params.useAssert)
|
||||
if (global.params.useAssert == CHECKENABLEon)
|
||||
VersionCondition::addPredefinedGlobalIdent ("assert");
|
||||
|
||||
if (global.params.useArrayBounds == BOUNDSCHECKoff)
|
||||
if (global.params.useArrayBounds == CHECKENABLEoff)
|
||||
VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
|
||||
|
||||
if (global.params.betterC)
|
||||
|
|
|
@ -1749,13 +1749,13 @@ array_bounds_check (void)
|
|||
|
||||
switch (global.params.useArrayBounds)
|
||||
{
|
||||
case BOUNDSCHECKoff:
|
||||
case CHECKENABLEoff:
|
||||
return false;
|
||||
|
||||
case BOUNDSCHECKon:
|
||||
case CHECKENABLEon:
|
||||
return true;
|
||||
|
||||
case BOUNDSCHECKsafeonly:
|
||||
case CHECKENABLEsafeonly:
|
||||
/* For D2 safe functions only. */
|
||||
fd = d_function_chain->function;
|
||||
if (fd && fd->type->ty == Tfunction)
|
||||
|
@ -2376,8 +2376,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd)
|
|||
of the calling function non-locally. So we add all parameters with nested
|
||||
refs to the function frame, this should also mean overriding methods will
|
||||
have the same frame layout when inheriting a contract. */
|
||||
if ((global.params.useIn && fd->frequire)
|
||||
|| (global.params.useOut && fd->fensure))
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
|
||||
{
|
||||
if (fd->parameters)
|
||||
{
|
||||
|
@ -2563,8 +2563,8 @@ get_frameinfo (FuncDeclaration *fd)
|
|||
|
||||
/* In checkNestedReference, references from contracts are not added to the
|
||||
closureVars array, so assume all parameters referenced. */
|
||||
if ((global.params.useIn && fd->frequire)
|
||||
|| (global.params.useOut && fd->fensure))
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
|
||||
FRAMEINFO_CREATES_FRAME (ffi) = 1;
|
||||
|
||||
/* If however `fd` is nested (deeply) in a function that creates a
|
||||
|
|
|
@ -279,12 +279,12 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options)
|
|||
global.vendor = lang_hooks.name;
|
||||
global.params.argv0 = xstrdup (decoded_options[0].arg);
|
||||
global.params.link = true;
|
||||
global.params.useAssert = true;
|
||||
global.params.useInvariants = true;
|
||||
global.params.useIn = true;
|
||||
global.params.useOut = true;
|
||||
global.params.useArrayBounds = BOUNDSCHECKdefault;
|
||||
global.params.useSwitchError = true;
|
||||
global.params.useAssert = CHECKENABLEdefault;
|
||||
global.params.useInvariants = CHECKENABLEdefault;
|
||||
global.params.useIn = CHECKENABLEdefault;
|
||||
global.params.useOut = CHECKENABLEdefault;
|
||||
global.params.useArrayBounds = CHECKENABLEdefault;
|
||||
global.params.useSwitchError = CHECKENABLEdefault;
|
||||
global.params.useModuleInfo = true;
|
||||
global.params.useTypeInfo = true;
|
||||
global.params.useExceptions = true;
|
||||
|
@ -339,9 +339,6 @@ d_init_options_struct (gcc_options *opts)
|
|||
opts->x_flag_errno_math = 0;
|
||||
opts->frontend_set_flag_errno_math = true;
|
||||
|
||||
/* Keep in sync with existing -fbounds-check flag. */
|
||||
opts->x_flag_bounds_check = global.params.useArrayBounds;
|
||||
|
||||
/* D says that signed overflow is precisely defined. */
|
||||
opts->x_flag_wrapv = 1;
|
||||
}
|
||||
|
@ -424,17 +421,16 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_fassert:
|
||||
global.params.useAssert = value;
|
||||
global.params.useAssert = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_fbounds_check:
|
||||
global.params.useArrayBounds = value
|
||||
? BOUNDSCHECKon : BOUNDSCHECKoff;
|
||||
global.params.useArrayBounds = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_fbounds_check_:
|
||||
global.params.useArrayBounds = (value == 2) ? BOUNDSCHECKon
|
||||
: (value == 1) ? BOUNDSCHECKsafeonly : BOUNDSCHECKoff;
|
||||
global.params.useArrayBounds = (value == 2) ? CHECKENABLEon
|
||||
: (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_fdebug:
|
||||
|
@ -496,7 +492,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_finvariants:
|
||||
global.params.useInvariants = value;
|
||||
global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_fmain:
|
||||
|
@ -518,11 +514,11 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_fpostconditions:
|
||||
global.params.useOut = value;
|
||||
global.params.useOut = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_fpreconditions:
|
||||
global.params.useIn = value;
|
||||
global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_frelease:
|
||||
|
@ -534,7 +530,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_fswitch_errors:
|
||||
global.params.useSwitchError = value;
|
||||
global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff;
|
||||
break;
|
||||
|
||||
case OPT_ftransition_all:
|
||||
|
@ -727,29 +723,46 @@ d_post_options (const char ** fn)
|
|||
*fn = filename;
|
||||
|
||||
/* Release mode doesn't turn off bounds checking for safe functions. */
|
||||
if (global.params.useArrayBounds == BOUNDSCHECKdefault)
|
||||
if (global.params.useArrayBounds == CHECKENABLEdefault)
|
||||
{
|
||||
global.params.useArrayBounds = global.params.release
|
||||
? BOUNDSCHECKsafeonly : BOUNDSCHECKon;
|
||||
flag_bounds_check = !global.params.release;
|
||||
? CHECKENABLEsafeonly : CHECKENABLEon;
|
||||
}
|
||||
|
||||
if (global.params.release)
|
||||
/* Assert code is generated if unittests are being compiled also, even if
|
||||
release mode is turned on. */
|
||||
if (global.params.useAssert == CHECKENABLEdefault)
|
||||
{
|
||||
if (!global_options_set.x_flag_invariants)
|
||||
global.params.useInvariants = false;
|
||||
if (global.params.useUnitTests || !global.params.release)
|
||||
global.params.useAssert = CHECKENABLEon;
|
||||
else
|
||||
global.params.useAssert = CHECKENABLEoff;
|
||||
}
|
||||
|
||||
if (!global_options_set.x_flag_preconditions)
|
||||
global.params.useIn = false;
|
||||
/* Checks for switches without a default are turned off in release mode. */
|
||||
if (global.params.useSwitchError == CHECKENABLEdefault)
|
||||
{
|
||||
global.params.useSwitchError = global.params.release
|
||||
? CHECKENABLEoff : CHECKENABLEon;
|
||||
}
|
||||
|
||||
if (!global_options_set.x_flag_postconditions)
|
||||
global.params.useOut = false;
|
||||
/* Contracts are turned off in release mode. */
|
||||
if (global.params.useInvariants == CHECKENABLEdefault)
|
||||
{
|
||||
global.params.useInvariants = global.params.release
|
||||
? CHECKENABLEoff : CHECKENABLEon;
|
||||
}
|
||||
|
||||
if (!global_options_set.x_flag_assert)
|
||||
global.params.useAssert = false;
|
||||
if (global.params.useIn == CHECKENABLEdefault)
|
||||
{
|
||||
global.params.useIn = global.params.release
|
||||
? CHECKENABLEoff : CHECKENABLEon;
|
||||
}
|
||||
|
||||
if (!global_options_set.x_flag_switch_errors)
|
||||
global.params.useSwitchError = false;
|
||||
if (global.params.useOut == CHECKENABLEdefault)
|
||||
{
|
||||
global.params.useOut = global.params.release
|
||||
? CHECKENABLEoff : CHECKENABLEon;
|
||||
}
|
||||
|
||||
if (global.params.betterC)
|
||||
|
@ -766,6 +779,9 @@ d_post_options (const char ** fn)
|
|||
global.params.checkAction = CHECKACTION_halt;
|
||||
}
|
||||
|
||||
/* Keep in sync with existing -fbounds-check flag. */
|
||||
flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);
|
||||
|
||||
/* Turn off partitioning unless it was explicitly requested, as it doesn't
|
||||
work with D exception chaining, where EH handler uses LSDA to determine
|
||||
whether two thrown exception are in the same context. */
|
||||
|
@ -784,9 +800,6 @@ d_post_options (const char ** fn)
|
|||
if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
|
||||
flag_excess_precision = EXCESS_PRECISION_STANDARD;
|
||||
|
||||
if (global.params.useUnitTests)
|
||||
global.params.useAssert = true;
|
||||
|
||||
global.params.symdebug = write_symbols != NO_DEBUG;
|
||||
global.params.useInline = flag_inline_functions;
|
||||
global.params.showColumns = flag_show_column;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
56f0a65c493463633a293d71faf37cdf710041ef
|
||||
f5638c7b8a6912858a9b51987df6a725e6796dc9
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -2451,7 +2451,7 @@ public:
|
|||
sc->fieldinit[i] |= CSXhalt;
|
||||
}
|
||||
|
||||
if (!global.params.useAssert)
|
||||
if (global.params.useAssert == CHECKENABLEoff)
|
||||
{
|
||||
Expression *e = new HaltExp(exp->loc);
|
||||
e = semantic(e, sc);
|
||||
|
|
|
@ -1668,7 +1668,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||
Scope *scout = NULL;
|
||||
if (needEnsure || addPostInvariant())
|
||||
{
|
||||
if ((needEnsure && global.params.useOut) || fpostinv)
|
||||
if ((needEnsure && global.params.useOut == CHECKENABLEon) || fpostinv)
|
||||
{
|
||||
returnLabel = new LabelDsymbol(Id::returnLabel);
|
||||
}
|
||||
|
@ -1915,7 +1915,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||
error("has no return statement, but is expected to return a value of type %s", f->next->toChars());
|
||||
else
|
||||
error("no return exp; or assert(0); at end of function");
|
||||
if (global.params.useAssert &&
|
||||
if (global.params.useAssert == CHECKENABLEon &&
|
||||
!global.params.useInline)
|
||||
{
|
||||
/* Add an assert(0, msg); where the missing return
|
||||
|
@ -2048,7 +2048,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||
|
||||
sc2 = sc2->pop();
|
||||
|
||||
if (!global.params.useIn)
|
||||
if (global.params.useIn == CHECKENABLEoff)
|
||||
freq = NULL;
|
||||
}
|
||||
|
||||
|
@ -2072,7 +2072,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||
|
||||
sc2 = sc2->pop();
|
||||
|
||||
if (!global.params.useOut)
|
||||
if (global.params.useOut == CHECKENABLEoff)
|
||||
fens = NULL;
|
||||
}
|
||||
|
||||
|
@ -4135,7 +4135,7 @@ bool FuncDeclaration::addPreInvariant()
|
|||
AggregateDeclaration *ad = isThis();
|
||||
ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
|
||||
return (ad && !(cd && cd->isCPPclass()) &&
|
||||
global.params.useInvariants &&
|
||||
global.params.useInvariants == CHECKENABLEon &&
|
||||
(protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
|
||||
!naked);
|
||||
}
|
||||
|
@ -4146,7 +4146,7 @@ bool FuncDeclaration::addPostInvariant()
|
|||
ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
|
||||
return (ad && !(cd && cd->isCPPclass()) &&
|
||||
ad->inv &&
|
||||
global.params.useInvariants &&
|
||||
global.params.useInvariants == CHECKENABLEon &&
|
||||
(protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
|
||||
!naked);
|
||||
}
|
||||
|
@ -4927,7 +4927,7 @@ bool CtorDeclaration::addPreInvariant()
|
|||
|
||||
bool CtorDeclaration::addPostInvariant()
|
||||
{
|
||||
return (isThis() && vthis && global.params.useInvariants);
|
||||
return (isThis() && vthis && global.params.useInvariants == CHECKENABLEon);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4995,7 +4995,7 @@ bool PostBlitDeclaration::addPreInvariant()
|
|||
|
||||
bool PostBlitDeclaration::addPostInvariant()
|
||||
{
|
||||
return (isThis() && vthis && global.params.useInvariants);
|
||||
return (isThis() && vthis && global.params.useInvariants == CHECKENABLEon);
|
||||
}
|
||||
|
||||
bool PostBlitDeclaration::isVirtual()
|
||||
|
@ -5067,7 +5067,7 @@ bool DtorDeclaration::overloadInsert(Dsymbol *)
|
|||
|
||||
bool DtorDeclaration::addPreInvariant()
|
||||
{
|
||||
return (isThis() && vthis && global.params.useInvariants);
|
||||
return (isThis() && vthis && global.params.useInvariants == CHECKENABLEon);
|
||||
}
|
||||
|
||||
bool DtorDeclaration::addPostInvariant()
|
||||
|
|
|
@ -28,12 +28,13 @@ enum
|
|||
};
|
||||
|
||||
// The state of array bounds checking
|
||||
enum BOUNDSCHECK
|
||||
typedef unsigned char CHECKENABLE;
|
||||
enum
|
||||
{
|
||||
BOUNDSCHECKdefault, // initial value
|
||||
BOUNDSCHECKoff, // never do bounds checking
|
||||
BOUNDSCHECKon, // always do bounds checking
|
||||
BOUNDSCHECKsafeonly // do bounds checking only in @safe functions
|
||||
CHECKENABLEdefault, // initial value
|
||||
CHECKENABLEoff, // never do bounds checking
|
||||
CHECKENABLEon, // always do bounds checking
|
||||
CHECKENABLEsafeonly // do bounds checking only in @safe functions
|
||||
};
|
||||
|
||||
typedef unsigned char CHECKACTION;
|
||||
|
@ -105,12 +106,7 @@ struct Param
|
|||
bool hasObjectiveC; // target supports Objective-C
|
||||
bool mscoff; // for Win32: write COFF object files instead of OMF
|
||||
Diagnostic useDeprecated;
|
||||
bool useAssert; // generate runtime code for assert()'s
|
||||
bool useInvariants; // generate class invariant checks
|
||||
bool useIn; // generate precondition checks
|
||||
bool useOut; // generate postcondition checks
|
||||
bool stackstomp; // add stack stomping code
|
||||
bool useSwitchError; // check for switches without a default
|
||||
bool useUnitTests; // generate unittest code
|
||||
bool useInline; // inline expand functions
|
||||
bool useDIP25; // implement http://wiki.dlang.org/DIP25
|
||||
|
@ -138,7 +134,14 @@ struct Param
|
|||
|
||||
CPU cpu; // CPU instruction set to target
|
||||
|
||||
BOUNDSCHECK useArrayBounds; // when to generate code for array bounds checks
|
||||
CHECKENABLE useInvariants; // generate class invariant checks
|
||||
CHECKENABLE useIn; // generate precondition checks
|
||||
CHECKENABLE useOut; // generate postcondition checks
|
||||
CHECKENABLE useArrayBounds; // when to generate code for array bounds checks
|
||||
CHECKENABLE useAssert; // when to generate code for assert()'s
|
||||
CHECKENABLE useSwitchError; // check for switches without a default
|
||||
CHECKENABLE boundscheck; // state of -boundscheck switch
|
||||
|
||||
CHECKACTION checkAction; // action to take when bounds, asserts or switch defaults are violated
|
||||
|
||||
const char *argv0; // program name
|
||||
|
|
|
@ -2329,7 +2329,7 @@ public:
|
|||
needswitcherror = true;
|
||||
}
|
||||
|
||||
if (!sc->sw->sdefault && (!ss->isFinal || needswitcherror || global.params.useAssert))
|
||||
if (!sc->sw->sdefault && (!ss->isFinal || needswitcherror || global.params.useAssert == CHECKENABLEon))
|
||||
{
|
||||
ss->hasNoDefault = 1;
|
||||
|
||||
|
@ -2341,7 +2341,7 @@ public:
|
|||
CompoundStatement *cs;
|
||||
Statement *s;
|
||||
|
||||
if (global.params.useSwitchError &&
|
||||
if (global.params.useSwitchError == CHECKENABLEon &&
|
||||
global.params.checkAction != CHECKACTION_halt)
|
||||
{
|
||||
if (global.params.checkAction == CHECKACTION_C)
|
||||
|
|
|
@ -1980,7 +1980,7 @@ public:
|
|||
tree assert_pass = void_node;
|
||||
tree assert_fail;
|
||||
|
||||
if (global.params.useAssert
|
||||
if (global.params.useAssert == CHECKENABLEon
|
||||
&& global.params.checkAction == CHECKACTION_D)
|
||||
{
|
||||
/* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
|
||||
|
@ -1999,7 +1999,7 @@ public:
|
|||
/* Build a call to _d_assert(). */
|
||||
assert_fail = d_assert_call (e->loc, libcall, tmsg);
|
||||
|
||||
if (global.params.useInvariants)
|
||||
if (global.params.useInvariants == CHECKENABLEon)
|
||||
{
|
||||
/* If the condition is a D class or struct object with an invariant,
|
||||
call it if the condition result is true. */
|
||||
|
@ -2025,7 +2025,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (global.params.useAssert
|
||||
else if (global.params.useAssert == CHECKENABLEon
|
||||
&& global.params.checkAction == CHECKACTION_C)
|
||||
{
|
||||
/* Generate: __builtin_trap() */
|
||||
|
|
Loading…
Reference in New Issue