diff mbox series

[committed] d: Merge upstream dmd 4be011355.

Message ID 20200625153828.2304469-4-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd 4be011355. | expand

Commit Message

Iain Buclaw June 25, 2020, 3:38 p.m. UTC
Hi,

This patch merges the D front-end implementation with upstream dmd
4be011355.  Fixes self-assignment warnings seen when compiling with
clang.

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

Regards
Iain.

---
gcc/d/ChangeLog:

	PR d/95075
	* dmd/MERGE: Merge upstream dmd 4be011355.
---
 gcc/d/dmd/MERGE    |  2 +-
 gcc/d/dmd/dscope.c | 98 +++++++++++++++++++++++++---------------------
 2 files changed, 55 insertions(+), 45 deletions(-)
diff mbox series

Patch

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 0d50149a750..7de89351482 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-90450f3ef6ab8551b5f383d8c6190f80034dbf93
+4be011355dd2c5e2e54b99f9369d5faeabca2ca5
 
 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/dscope.c b/gcc/d/dmd/dscope.c
index 32aa965a932..32caf7d2409 100644
--- a/gcc/d/dmd/dscope.c
+++ b/gcc/d/dmd/dscope.c
@@ -291,54 +291,64 @@  unsigned *Scope::saveFieldInit()
     return fi;
 }
 
-static bool mergeFieldInit(unsigned &fieldInit, unsigned fi, bool mustInit)
+/****************************************
+ * Merge `b` flow analysis results into `a`.
+ * Params:
+ *      a = the path to merge fi into
+ *      b = the other path
+ * Returns:
+ *      false means either `a` or `b` skips initialization
+ */
+static bool mergeFieldInit(unsigned &a, const unsigned b)
 {
-    if (fi != fieldInit)
-    {
-        // Have any branches returned?
-        bool aRet = (fi        & CSXreturn) != 0;
-        bool bRet = (fieldInit & CSXreturn) != 0;
+    if (b == a)
+        return true;
 
-        // Have any branches halted?
-        bool aHalt = (fi        & CSXhalt) != 0;
-        bool bHalt = (fieldInit & CSXhalt) != 0;
+    // Have any branches returned?
+    bool aRet = (a & CSXreturn) != 0;
+    bool bRet = (b & CSXreturn) != 0;
 
-        bool ok;
+    // Have any branches halted?
+    bool aHalt = (a & CSXhalt) != 0;
+    bool bHalt = (b & CSXhalt) != 0;
 
-        if (aHalt && bHalt)
-        {
-            ok = true;
-            fieldInit = CSXhalt;
-        }
-        else if (!aHalt && aRet)
-        {
-            ok = !mustInit || (fi & CSXthis_ctor);
-            fieldInit = fieldInit;
-        }
-        else if (!bHalt && bRet)
-        {
-            ok = !mustInit || (fieldInit & CSXthis_ctor);
-            fieldInit = fi;
-        }
-        else if (aHalt)
-        {
-            ok = !mustInit || (fieldInit & CSXthis_ctor);
-            fieldInit = fieldInit;
-        }
-        else if (bHalt)
-        {
-            ok = !mustInit || (fi & CSXthis_ctor);
-            fieldInit = fi;
-        }
-        else
-        {
-            ok = !mustInit || !((fieldInit ^ fi) & CSXthis_ctor);
-            fieldInit |= fi;
-        }
+    if (aHalt && bHalt)
+    {
+        a = CSXhalt;
+        return true;
+    }
 
-        return ok;
+    // The logic here is to prefer the branch that neither halts nor returns.
+    bool ok;
+    if (!bHalt && bRet)
+    {
+        // Branch b returns, no merging required.
+        ok = (b & CSXthis_ctor);
+    }
+    else if (!aHalt && aRet)
+    {
+        // Branch a returns, but b doesn't, b takes precedence.
+        ok = (a & CSXthis_ctor);
+        a = b;
+    }
+    else if (bHalt)
+    {
+        // Branch b halts, no merging required.
+        ok = (a & CSXthis_ctor);
+    }
+    else if (aHalt)
+    {
+        // Branch a halts, but b doesn't, b takes precedence
+        ok = (b & CSXthis_ctor);
+        a = b;
+    }
+    else
+    {
+        // Neither branch returns nor halts, merge flags
+        ok = !((a ^ b) & CSXthis_ctor);
+        a |= b;
     }
-    return true;
+    return ok;
 }
 
 void Scope::mergeFieldInit(Loc loc, unsigned *fies)
@@ -356,9 +366,9 @@  void Scope::mergeFieldInit(Loc loc, unsigned *fies)
             bool mustInit = (v->storage_class & STCnodefaultctor ||
                              v->type->needsNested());
 
-            if (!::mergeFieldInit(fieldinit[i], fies[i], mustInit))
+            if (!::mergeFieldInit(fieldinit[i], fies[i]) && mustInit)
             {
-                ::error(loc, "one path skips field %s", ad->fields[i]->toChars());
+                ::error(loc, "one path skips field %s", v->toChars());
             }
         }
     }