aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-06-24 08:35:58 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-06-25 17:02:47 +0200
commit1b7b352a8379dbdd74c962d11951982e21e20f13 (patch)
treec970f8b3a33d694ea0fc0739646fc00e81fa7391 /gcc/d/dmd
parent1d19c9cd3dd99ba8885c0fc93223918399f73939 (diff)
downloadgcc-1b7b352a8379dbdd74c962d11951982e21e20f13.zip
gcc-1b7b352a8379dbdd74c962d11951982e21e20f13.tar.gz
gcc-1b7b352a8379dbdd74c962d11951982e21e20f13.tar.bz2
d: Merge upstream dmd 4be011355.
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.
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/dscope.c98
2 files changed, 55 insertions, 45 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 0d50149..7de8935 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 32aa965..32caf7d 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());
}
}
}