d: Merge upstream dmd 4be011355.
authorIain Buclaw <ibuclaw@gdcproject.org>
Wed, 24 Jun 2020 06:35:58 +0000 (08:35 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Thu, 25 Jun 2020 15:02:47 +0000 (17:02 +0200)
Fixes self-assignment warnings seen when compiling with clang.

Reviewed-on: https://github.com/dlang/dmd/pull/11315

gcc/d/ChangeLog:

PR d/95075
* dmd/MERGE: Merge upstream dmd 4be011355.

gcc/d/dmd/MERGE
gcc/d/dmd/dscope.c

index 0d50149a750e96545bb5f6835622962d6cf8f016..7de89351482cd1a4accc3af904fcb7b33c8c1e16 100644 (file)
@@ -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.
index 32aa965a93295df7add088a835ac29f5e81b6124..32caf7d24097dd3e24acabca75e4f4dccf5b248e 100644 (file)
@@ -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());
             }
         }
     }