diff mbox series

[committed] d: Merge upstream dmd f5638c7b8.

Message ID 20200605181819.18302-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd f5638c7b8. | expand

Commit Message

Iain Buclaw June 5, 2020, 6:18 p.m. UTC
Hi,

This patch merges the D front-end implementation with upstream dmd
f5638c7b8.  Adds a CHECKENABLE enum, uses it for all contract parameters
for consistency in state checking.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.


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.
---
 gcc/d/d-builtins.cc       |  4 +-
 gcc/d/d-codegen.cc        | 14 +++----
 gcc/d/d-lang.cc           | 83 ++++++++++++++++++++++-----------------
 gcc/d/dmd/MERGE           |  2 +-
 gcc/d/dmd/expressionsem.c |  2 +-
 gcc/d/dmd/func.c          | 18 ++++-----
 gcc/d/dmd/globals.h       | 25 ++++++------
 gcc/d/dmd/statementsem.c  |  4 +-
 gcc/d/expr.cc             |  6 +--
 9 files changed, 87 insertions(+), 71 deletions(-)
diff mbox series

Patch

diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index cbc74558106..bd7e3eb15d7 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -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)
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index cf98d4be7e9..301793f1b74 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -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
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 51a87a01813..203039e9ecf 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -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;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index f413bd17514..3248bf7c982 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -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.
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index ffcfeb4e6cd..75e4d130564 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -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);
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index 807565df12b..eb8d5dbf2dd 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -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()
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index aac4abcd339..be75fc09d2e 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -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
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index bfcb4b4db9c..cd48d9c03cf 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -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)
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 461124f704e..562e35a0f7c 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -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()  */