From 2d128bd9344f975bd41a62b2b6c8c4c6c4e6546c Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Sat, 5 Oct 2024 20:33:45 +0800 Subject: [PATCH] `TemplateInstance.equalsx` use early return (#16940) --- compiler/src/dmd/dtemplate.d | 89 +++++++++++++++++------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index 69a92eacaf3..63c18f8c58f 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -3998,66 +3998,63 @@ extern (C++) class TemplateInstance : ScopeDsymbol if (enclosing != ti.enclosing) { //printf("test2 enclosing %s ti.enclosing %s\n", enclosing ? enclosing.toChars() : "", ti.enclosing ? ti.enclosing.toChars() : ""); - goto Lnotequals; + return false; } //printf("parent = %s, ti.parent = %s\n", parent.toPrettyChars(), ti.parent.toPrettyChars()); if (!arrayObjectMatch(tdtypes, ti.tdtypes)) - goto Lnotequals; + return false; /* Template functions may have different instantiations based on * "auto ref" parameters. */ - if (auto fd = ti.toAlias().isFuncDeclaration()) - { - if (!fd.errors) - { - auto resolvedArgs = fd.type.isTypeFunction().resolveNamedArgs( - ArgumentList(this.fargs, this.fnames), null); + auto fd = ti.toAlias().isFuncDeclaration(); + if (!fd) + return true; + if (fd.errors) + return true; - // resolvedArgs can be null when there's an error: fail_compilation/fail14669.d - // In that case, equalsx returns true to prevent endless template instantiations - // However, it can also mean the function was explicitly instantiated - // without function arguments: fail_compilation/fail14669 - // Hence the following check: - if (this.fargs && !resolvedArgs) - return true; + auto resolvedArgs = fd.type.isTypeFunction().resolveNamedArgs( + ArgumentList(this.fargs, this.fnames), null); - Expression[] args = resolvedArgs ? (*resolvedArgs)[] : []; + // resolvedArgs can be null when there's an error: fail_compilation/fail14669.d + // In that case, equalsx returns true to prevent endless template instantiations + // However, it can also mean the function was explicitly instantiated + // without function arguments: fail_compilation/fail14669 + // Hence the following check: + if (this.fargs && !resolvedArgs) + return true; - auto fparameters = fd.getParameterList(); - size_t nfparams = fparameters.length; // Num function parameters - for (size_t j = 0; j < nfparams; j++) - { - Parameter fparam = fparameters[j]; - if (fparam.storageClass & STC.autoref) // if "auto ref" - { - Expression farg = (j < args.length) ? args[j] : fparam.defaultArg; - // resolveNamedArgs strips trailing nulls / default params - // when it doesn't anymore, the ternary can be replaced with: - // assert(j < resolvedArgs.length); - if (!farg) - farg = fparam.defaultArg; - if (!farg) - goto Lnotequals; - if (farg.isLvalue()) - { - if (!(fparam.storageClass & STC.ref_)) - goto Lnotequals; // auto ref's don't match - } - else - { - if (fparam.storageClass & STC.ref_) - goto Lnotequals; // auto ref's don't match - } - } - } + Expression[] args = resolvedArgs ? (*resolvedArgs)[] : []; + + auto fparameters = fd.getParameterList(); + size_t nfparams = fparameters.length; // Num function parameters + for (size_t j = 0; j < nfparams; j++) + { + Parameter fparam = fparameters[j]; + if (!(fparam.storageClass & STC.autoref) ) // if "auto ref" + continue; + + Expression farg = (j < args.length) ? args[j] : fparam.defaultArg; + // resolveNamedArgs strips trailing nulls / default params + // when it doesn't anymore, the ternary can be replaced with: + // assert(j < resolvedArgs.length); + if (!farg) + farg = fparam.defaultArg; + if (!farg) + return false; + if (farg.isLvalue()) + { + if (!(fparam.storageClass & STC.ref_)) + return false; // auto ref's don't match + } + else + { + if (fparam.storageClass & STC.ref_) + return false; // auto ref's don't match } } return true; - - Lnotequals: - return false; } extern (D) final size_t toHash()