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

Function template ordering, bug 294539.

This commit is contained in:
Markus Schorn 2009-11-09 17:47:02 +00:00
parent 8d5a128bc4
commit 57150dcb15
3 changed files with 67 additions and 44 deletions

View file

@ -4227,4 +4227,22 @@ public class AST2TemplateTests extends AST2BaseTest {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// template <typename T> void func(T* t) {};
// template <typename T> void func(T& t) {};
// void test() {
// int* a;
// func(a);
// }
//
// template <typename T> void func1(const T* const t) {};
// template <typename T> void func1(T* const t) {};
// void test2() {
// const int* a;
// func1 (a);
// }
public void testFunctionTemplateOrdering_294539() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -653,7 +653,7 @@ public class CPPTemplates {
result[i]= tmplArg;
}
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map))
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map, false))
return null;
for (int i = 0; i < length; i++) {
@ -1456,7 +1456,8 @@ public class CPPTemplates {
* Deduces the mapping for the template parameters from the function parameters,
* returns <code>false</code> if there is no mapping.
*/
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException{
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template,
IType[] fnArgs, CPPTemplateParameterMap map, boolean checkExactMatch) throws DOMException {
try {
IType[] fnPars = template.getType().getParameterTypes();
if (fnPars.length == 0)
@ -1474,7 +1475,8 @@ public class CPPTemplates {
for (int j= 0; j < len; j++) {
IType par= instPars[j];
if (isDependentType(par)) {
boolean isDependentPar= isDependentType(par);
if (checkExactMatch || isDependentPar) {
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
par= SemanticUtil.adjustParameterType(par, false);
// 14.8.2.1.2 and 14.8.2.1.3
@ -1483,46 +1485,53 @@ public class CPPTemplates {
par= getParameterTypeForDeduction(par, isReferenceType);
// 14.8.2.1.3
CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
if (!(pcheck instanceof ICPPTemplateParameter)) {
par= pcheck;
arg= SemanticUtil.getNestedType(arg, CVTYPE);
IType argcheck= arg;
if (par instanceof IPointerType && arg instanceof IPointerType) {
pcheck= ((IPointerType) par).getType();
argcheck= ((IPointerType) arg).getType();
if (pcheck instanceof ICPPTemplateParameter) {
pcheck= null;
} else {
cvPar= SemanticUtil.getCVQualifier(pcheck);
cvArg= SemanticUtil.getCVQualifier(argcheck);
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
} else {
if (!checkExactMatch) {
CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
if (!(pcheck instanceof ICPPTemplateParameter)) {
par= pcheck;
arg= SemanticUtil.getNestedType(arg, CVTYPE);
IType argcheck= arg;
if (par instanceof IPointerType && arg instanceof IPointerType) {
pcheck= ((IPointerType) par).getType();
argcheck= ((IPointerType) arg).getType();
if (pcheck instanceof ICPPTemplateParameter) {
pcheck= null;
} else {
cvPar= SemanticUtil.getCVQualifier(pcheck);
cvArg= SemanticUtil.getCVQualifier(argcheck);
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
} else {
pcheck= null;
}
}
}
}
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
if (pTemplate != null) {
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
if (aInst != null && aInst != argcheck) {
par= pcheck;
arg= aInst;
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
if (pTemplate != null) {
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
if (aInst != null && aInst != argcheck) {
par= pcheck;
arg= aInst;
}
}
}
}
}
}
if (!deduceTemplateParameterMap(par, arg, map)) {
if (isDependentPar && !deduceTemplateParameterMap(par, arg, map)) {
return false;
}
if (checkExactMatch) {
IType instantiated= instantiateType(par, map, null);
if (!instantiated.isSameType(arg))
return false;
}
}
}
return true;
@ -1844,7 +1853,7 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(2);
final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes();
if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, map))
if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, map, true))
return false;
final ICPPTemplateParameter[] tmplParams = f2.getTemplateParameters();
@ -1854,15 +1863,6 @@ public class CPPTemplates {
return false;
}
// length can be different in case of varargs or default arguments
IType[] params= f2.getType().getParameterTypes();
final int len= Math.min(params.length, transferredParameterTypes.length);
for (int i = 0; i <len; i++) {
IType instantiated= instantiateType(params[i], map, null);
// we need to be able to compare class instances from different caches here
if (!instantiated.isSameType(transferredParameterTypes[i]))
return false;
}
return true;
}

View file

@ -390,12 +390,17 @@ public class Conversions {
continue;
}
} else {
IType ptype= ptypes[0];
// We don't need to check the implicit conversion sequence it the type is void
if (ptype instanceof ICPPBasicType && ((ICPPBasicType) ptype).getKind() == Kind.eVoid)
continue;
if (ptypes.length > 1) {
IParameter[] pars = ctor.getParameters();
if (pars.length < 2 || !((ICPPParameter) pars[1]).hasDefaultValue())
continue;
}
c1= checkImplicitConversionSequence(sourceIsLValue, source, ptypes[0], UDCMode.noUDC, false);
c1= checkImplicitConversionSequence(sourceIsLValue, source, ptype, UDCMode.noUDC, false);
}
int cmp= c1.compareTo(cost1);
if (cmp <= 0) {