1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 02:06:01 +02:00

Bug 567217 - Avoid incorrect cache hits during the instantiation of alias template instances

Change-Id: I2f21b0a097f9d279b6e32d28acd68091e3b9ad76
This commit is contained in:
Nathan Ridge 2020-11-05 02:16:47 -05:00
parent 1d226f9273
commit 821c7e2277
3 changed files with 33 additions and 7 deletions

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
*/ */
public final class InstantiationContext { public final class InstantiationContext {
private CPPTemplateParameterMap parameterMap; private CPPTemplateParameterMap parameterMap;
private boolean forDeduction = false;
private int packOffset; private int packOffset;
private final ICPPSpecialization contextSpecialization; private final ICPPSpecialization contextSpecialization;
private boolean expandPack; private boolean expandPack;
@ -78,6 +79,15 @@ public final class InstantiationContext {
this(parameterMap, -1, null); 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 * Returns the mapping of template parameters to arguments, possibly {@code null} if the context doesn't
* contain it. * contain it.
@ -86,6 +96,13 @@ public final class InstantiationContext {
return parameterMap; return parameterMap;
} }
/**
* Returns whether the InstantiationContext was created during template argument deduction.
*/
public boolean isForDeduction() {
return forDeduction;
}
/** /**
* Adds a parameter mapping. * Adds a parameter mapping.
*/ */

View file

@ -135,7 +135,7 @@ public class TemplateArgumentDeduction {
break; break;
} }
par = CPPTemplates.instantiateType(par, new InstantiationContext(map)); par = CPPTemplates.instantiateType(par, InstantiationContext.forDeduction(map));
if (!SemanticUtil.isValidType(par)) if (!SemanticUtil.isValidType(par))
return false; return false;
@ -352,7 +352,7 @@ public class TemplateArgumentDeduction {
return null; return null;
IType par = template.getType(); IType par = template.getType();
InstantiationContext context = new InstantiationContext(map); InstantiationContext context = InstantiationContext.forDeduction(map);
par = CPPTemplates.instantiateType(par, context); par = CPPTemplates.instantiateType(par, context);
if (!SemanticUtil.isValidType(par)) if (!SemanticUtil.isValidType(par))
return null; return null;
@ -399,7 +399,7 @@ public class TemplateArgumentDeduction {
return null; return null;
} }
InstantiationContext context = new InstantiationContext(map); InstantiationContext context = InstantiationContext.forDeduction(map);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (result[i] == null) { if (result[i] == null) {
final ICPPTemplateParameter tpar = tmplParams[i]; final ICPPTemplateParameter tpar = tmplParams[i];
@ -427,7 +427,7 @@ public class TemplateArgumentDeduction {
return null; return null;
IType a = SemanticUtil.getSimplifiedType(ftype); IType a = SemanticUtil.getSimplifiedType(ftype);
InstantiationContext context = new InstantiationContext(map); InstantiationContext context = InstantiationContext.forDeduction(map);
IType p = CPPTemplates.instantiateType(template.getType(), context); IType p = CPPTemplates.instantiateType(template.getType(), context);
if (!SemanticUtil.isValidType(p)) if (!SemanticUtil.isValidType(p))
return null; return null;
@ -759,7 +759,7 @@ public class TemplateArgumentDeduction {
private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap,
boolean useDefaults) { boolean useDefaults) {
InstantiationContext context = new InstantiationContext(tpMap); InstantiationContext context = InstantiationContext.forDeduction(tpMap);
for (ICPPTemplateParameter tpar : pars) { for (ICPPTemplateParameter tpar : pars) {
if (tpar.isParameterPack()) { if (tpar.isParameterPack()) {
ICPPTemplateArgument[] deducedArgs = tpMap.getPackExpansion(tpar); ICPPTemplateArgument[] deducedArgs = tpMap.getPackExpansion(tpar);
@ -1022,7 +1022,7 @@ public class TemplateArgumentDeduction {
return true; // An unknown type may match anything. return true; // An unknown type may match anything.
// Verify that the resolved binding matches the argument type. // 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); IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context);
if (binding instanceof ICPPUnknownBinding) if (binding instanceof ICPPUnknownBinding)
return true; // An unknown type may match anything. return true; // An unknown type may match anything.

View file

@ -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.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -36,7 +37,15 @@ public class TypeInstantiationRequest {
public TypeInstantiationRequest(IType type, InstantiationContext context) { public TypeInstantiationRequest(IType type, InstantiationContext context) {
this.type = type; 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.packOffset = context.getPackOffset();
this.contextTypeSpecialization = context.getContextTypeSpecialization(); this.contextTypeSpecialization = context.getContextTypeSpecialization();
} }