diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 762badaa597..d1d279b2628 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -240,7 +240,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation { protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) { try { - return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point); + return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point, false); } catch (DOMException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 717bd660ad6..4d3afd83849 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -789,7 +789,7 @@ public class CPPTemplates { ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); ICPPTemplateArgument[] args = pspec.getTemplateArguments(); template= (ICPPClassTemplate) owner.specializeMember(template, point); - args= instantiateArguments(args, tpMap, -1, within, point); + args= instantiateArguments(args, tpMap, -1, within, point, false); spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args); } catch (DOMException e) { } @@ -1047,10 +1047,15 @@ public class CPPTemplates { } /** - * Instantiates arguments contained in an array. + * Instantiates arguments contained in an array. Instantiated arguments are checked for + * validity. If the {@code strict} parameter is {@code true}, the method returns {@code null} if + * any of the instantiated arguments are invalid. If the {@code strict} parameter is + * {@code false}, any invalid instantiated arguments are replaced by the corresponding original + * arguments. */ public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args, - ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) + ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, + IASTNode point, boolean strict) throws DOMException { // Don't create a new array until it's really needed. ICPPTemplateArgument[] result = args; @@ -1066,11 +1071,19 @@ public class CPPTemplates { } else if (packSize == PACK_SIZE_DEFER) { newArg= origArg; } else { - final int shift = packSize - 1; + int shift = packSize - 1; ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift]; System.arraycopy(result, 0, newResult, 0, i + resultShift); for (int j= 0; j < packSize; j++) { - newResult[i + resultShift + j]= instantiateArgument(origArg, tpMap, j, within, point); + newArg = instantiateArgument(origArg, tpMap, j, within, point); + if (!isValidArgument(newArg)) { + if (strict) + return null; + newResult = result; + shift = 0; + break; + } + newResult[i + resultShift + j]= newArg; } result= newResult; resultShift += shift; @@ -1078,7 +1091,13 @@ public class CPPTemplates { } } else { newArg = instantiateArgument(origArg, tpMap, packOffset, within, point); + if (!isValidArgument(newArg)) { + if (strict) + return null; + newArg = origArg; + } } + if (result != args) { result[i + resultShift]= newArg; } else if (newArg != origArg) { @@ -1122,12 +1141,15 @@ public class CPPTemplates { for (Integer key : positions) { ICPPTemplateArgument arg = orig.getArgument(key); if (arg != null) { - newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within, point)); + ICPPTemplateArgument newArg = instantiateArgument(arg, tpMap, packOffset, within, point); + if (!isValidArgument(newArg)) + newArg = arg; + newMap.put(key, newArg); } else { ICPPTemplateArgument[] args = orig.getPackExpansion(key); if (args != null) { try { - newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point)); + newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point, false)); } catch (DOMException e) { newMap.put(key, args); } @@ -1211,7 +1233,7 @@ public class CPPTemplates { final IBinding origClass = classInstance.getSpecializedBinding(); if (origClass instanceof ICPPClassType) { ICPPTemplateArgument[] args = classInstance.getTemplateArguments(); - ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point); + ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point, false); if (newArgs != args) { CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point); return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args); @@ -2061,12 +2083,7 @@ public class CPPTemplates { private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args, CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException { - args = instantiateArguments(args, tpMap, -1, null, point); - for (ICPPTemplateArgument arg : args) { - if (!isValidArgument(arg)) - return false; - } - return true; + return instantiateArguments(args, tpMap, -1, null, point, true) != null; } /** @@ -2124,7 +2141,7 @@ public class CPPTemplates { args[i]= arg; transferMap.put(param, arg); } - final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point); + final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point, false); // Deduce arguments for specialization 2 final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); @@ -2468,7 +2485,7 @@ public class CPPTemplates { if (unknown instanceof ICPPUnknownMemberClassInstance) { ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown; ICPPTemplateArgument[] args0 = ucli.getArguments(); - ICPPTemplateArgument[] args1 = instantiateArguments(args0, tpMap, packOffset, within, point); + ICPPTemplateArgument[] args1 = instantiateArguments(args0, tpMap, packOffset, within, point, false); if (args0 != args1 || !ot1.isSameType(ot0)) { args1= SemanticUtil.getSimplifiedArguments(args1); result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1); @@ -2486,7 +2503,7 @@ public class CPPTemplates { result= CPPSemantics.resolveUnknownName(s, unknown, point); if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) { ICPPTemplateArgument[] args1 = instantiateArguments( - ((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point); + ((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point, false); if (result instanceof ICPPClassTemplate) { result = instantiate((ICPPClassTemplate) result, args1, point); } @@ -2505,7 +2522,7 @@ public class CPPTemplates { ICPPTemplateArgument[] arguments = dci.getTemplateArguments(); ICPPTemplateArgument[] newArgs; try { - newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point); + newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, false); } catch (DOMException e) { return e.getProblem(); }