From 1b7b352a8379dbdd74c962d11951982e21e20f13 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Wed, 24 Jun 2020 08:35:58 +0200 Subject: [PATCH] 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. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/dscope.c | 98 +++++++++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 45 deletions(-) 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()); } } } -- 2.30.2