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:
parent
8d5a128bc4
commit
57150dcb15
3 changed files with 67 additions and 44 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue