1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 395243. Don't allow template arguments based on problem types.

This commit is contained in:
Sergey Prigogin 2013-01-07 15:00:03 -08:00
parent f9498e093a
commit 67ac152401
2 changed files with 36 additions and 19 deletions

View file

@ -240,7 +240,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args, protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) { ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
try { try {
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point); return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point, false);
} catch (DOMException e) { } catch (DOMException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }

View file

@ -789,7 +789,7 @@ public class CPPTemplates {
ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
ICPPTemplateArgument[] args = pspec.getTemplateArguments(); ICPPTemplateArgument[] args = pspec.getTemplateArguments();
template= (ICPPClassTemplate) owner.specializeMember(template, point); 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); spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
} catch (DOMException e) { } 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, 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 { throws DOMException {
// Don't create a new array until it's really needed. // Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args; ICPPTemplateArgument[] result = args;
@ -1066,11 +1071,19 @@ public class CPPTemplates {
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newArg= origArg; newArg= origArg;
} else { } else {
final int shift = packSize - 1; int shift = packSize - 1;
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift]; ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift); System.arraycopy(result, 0, newResult, 0, i + resultShift);
for (int j= 0; j < packSize; j++) { 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; result= newResult;
resultShift += shift; resultShift += shift;
@ -1078,7 +1091,13 @@ public class CPPTemplates {
} }
} else { } else {
newArg = instantiateArgument(origArg, tpMap, packOffset, within, point); newArg = instantiateArgument(origArg, tpMap, packOffset, within, point);
if (!isValidArgument(newArg)) {
if (strict)
return null;
newArg = origArg;
} }
}
if (result != args) { if (result != args) {
result[i + resultShift]= newArg; result[i + resultShift]= newArg;
} else if (newArg != origArg) { } else if (newArg != origArg) {
@ -1122,12 +1141,15 @@ public class CPPTemplates {
for (Integer key : positions) { for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key); ICPPTemplateArgument arg = orig.getArgument(key);
if (arg != null) { 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 { } else {
ICPPTemplateArgument[] args = orig.getPackExpansion(key); ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) { if (args != null) {
try { try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point)); newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point, false));
} catch (DOMException e) { } catch (DOMException e) {
newMap.put(key, args); newMap.put(key, args);
} }
@ -1211,7 +1233,7 @@ public class CPPTemplates {
final IBinding origClass = classInstance.getSpecializedBinding(); final IBinding origClass = classInstance.getSpecializedBinding();
if (origClass instanceof ICPPClassType) { if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments(); ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point); ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point, false);
if (newArgs != args) { if (newArgs != args) {
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point); CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point);
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args); return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
@ -2061,12 +2083,7 @@ public class CPPTemplates {
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args, private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException { CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
args = instantiateArguments(args, tpMap, -1, null, point); return instantiateArguments(args, tpMap, -1, null, point, true) != null;
for (ICPPTemplateArgument arg : args) {
if (!isValidArgument(arg))
return false;
}
return true;
} }
/** /**
@ -2124,7 +2141,7 @@ public class CPPTemplates {
args[i]= arg; args[i]= arg;
transferMap.put(param, 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 // Deduce arguments for specialization 2
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
@ -2468,7 +2485,7 @@ public class CPPTemplates {
if (unknown instanceof ICPPUnknownMemberClassInstance) { if (unknown instanceof ICPPUnknownMemberClassInstance) {
ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown; ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown;
ICPPTemplateArgument[] args0 = ucli.getArguments(); 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)) { if (args0 != args1 || !ot1.isSameType(ot0)) {
args1= SemanticUtil.getSimplifiedArguments(args1); args1= SemanticUtil.getSimplifiedArguments(args1);
result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1); result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1);
@ -2486,7 +2503,7 @@ public class CPPTemplates {
result= CPPSemantics.resolveUnknownName(s, unknown, point); result= CPPSemantics.resolveUnknownName(s, unknown, point);
if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) { if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] args1 = instantiateArguments( ICPPTemplateArgument[] args1 = instantiateArguments(
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point); ((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point, false);
if (result instanceof ICPPClassTemplate) { if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, args1, point); result = instantiate((ICPPClassTemplate) result, args1, point);
} }
@ -2505,7 +2522,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] arguments = dci.getTemplateArguments(); ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs; ICPPTemplateArgument[] newArgs;
try { try {
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point); newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, false);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }