From 821c7e2277883658d9f14a337113bfa6a70e46ca Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 5 Nov 2020 02:16:47 -0500 Subject: [PATCH] Bug 567217 - Avoid incorrect cache hits during the instantiation of alias template instances Change-Id: I2f21b0a097f9d279b6e32d28acd68091e3b9ad76 --- .../dom/parser/cpp/InstantiationContext.java | 17 +++++++++++++++++ .../semantics/TemplateArgumentDeduction.java | 12 ++++++------ .../cpp/semantics/TypeInstantiationRequest.java | 11 ++++++++++- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java index 61b889c2838..fb9063fb7d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; */ public final class InstantiationContext { private CPPTemplateParameterMap parameterMap; + private boolean forDeduction = false; private int packOffset; private final ICPPSpecialization contextSpecialization; private boolean expandPack; @@ -78,6 +79,15 @@ public final class InstantiationContext { this(parameterMap, -1, null); } + /** + * Create an InstantiationContext for a template parameter map, for use template argument deduction. + */ + public static InstantiationContext forDeduction(ICPPTemplateParameterMap parameterMap) { + InstantiationContext result = new InstantiationContext(parameterMap); + result.forDeduction = true; + return result; + } + /** * Returns the mapping of template parameters to arguments, possibly {@code null} if the context doesn't * contain it. @@ -86,6 +96,13 @@ public final class InstantiationContext { return parameterMap; } + /** + * Returns whether the InstantiationContext was created during template argument deduction. + */ + public boolean isForDeduction() { + return forDeduction; + } + /** * Adds a parameter mapping. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 1ceb1694fc9..2910f25211b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -135,7 +135,7 @@ public class TemplateArgumentDeduction { break; } - par = CPPTemplates.instantiateType(par, new InstantiationContext(map)); + par = CPPTemplates.instantiateType(par, InstantiationContext.forDeduction(map)); if (!SemanticUtil.isValidType(par)) return false; @@ -352,7 +352,7 @@ public class TemplateArgumentDeduction { return null; IType par = template.getType(); - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); par = CPPTemplates.instantiateType(par, context); if (!SemanticUtil.isValidType(par)) return null; @@ -399,7 +399,7 @@ public class TemplateArgumentDeduction { return null; } - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); for (int i = 0; i < length; i++) { if (result[i] == null) { final ICPPTemplateParameter tpar = tmplParams[i]; @@ -427,7 +427,7 @@ public class TemplateArgumentDeduction { return null; IType a = SemanticUtil.getSimplifiedType(ftype); - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); IType p = CPPTemplates.instantiateType(template.getType(), context); if (!SemanticUtil.isValidType(p)) return null; @@ -759,7 +759,7 @@ public class TemplateArgumentDeduction { private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, boolean useDefaults) { - InstantiationContext context = new InstantiationContext(tpMap); + InstantiationContext context = InstantiationContext.forDeduction(tpMap); for (ICPPTemplateParameter tpar : pars) { if (tpar.isParameterPack()) { ICPPTemplateArgument[] deducedArgs = tpMap.getPackExpansion(tpar); @@ -1022,7 +1022,7 @@ public class TemplateArgumentDeduction { return true; // An unknown type may match anything. // Verify that the resolved binding matches the argument type. - InstantiationContext context = new InstantiationContext(fDeducedArgs); + InstantiationContext context = InstantiationContext.forDeduction(fDeducedArgs); IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context); if (binding instanceof ICPPUnknownBinding) return true; // An unknown type may match anything. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java index 96d652981f5..4e2cb16f80b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; import org.eclipse.core.runtime.CoreException; @@ -36,7 +37,15 @@ public class TypeInstantiationRequest { public TypeInstantiationRequest(IType type, InstantiationContext context) { this.type = type; - this.parameterMap = context.getParameterMap(); + /* + * If the InstantiationContext was created during template argument deduction, its parameter map + * can be modified later in the deduction process. Since the TypeInstantiationRequest is used + * as a key in various caches, we don't want the map changing after constructing this object, + * so clone the map is such cases. + */ + this.parameterMap = context.isForDeduction() + ? new CPPTemplateParameterMap((CPPTemplateParameterMap) context.getParameterMap()) + : context.getParameterMap(); this.packOffset = context.getPackOffset(); this.contextTypeSpecialization = context.getContextTypeSpecialization(); }