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 204289917de..d659b80e527 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 @@ -143,6 +143,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; /** @@ -678,9 +679,9 @@ public class CPPTemplates { ICPPTemplateArgument[] result = new ICPPTemplateArgument[length]; IType a= SemanticUtil.getSimplifiedType(conversionType); - final boolean isReferenceType = a instanceof ICPPReferenceType; - final IType p= getArgumentTypeForDeduction(template.getType().getReturnType(), isReferenceType); - a= getParameterTypeForDeduction(a, isReferenceType); + IType p= template.getType().getReturnType(); + p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType); + a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF); if (!deduceTemplateParameterMap(p, a, map)) { return null; } @@ -1478,17 +1479,17 @@ public class CPPTemplates { 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 - final boolean isReferenceType = par instanceof ICPPReferenceType; - IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceType); - par= getParameterTypeForDeduction(par, isReferenceType); + // 14.8.2.1-2 + final boolean isReferenceTypeParameter = par instanceof ICPPReferenceType; + IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceTypeParameter); + if (isReferenceTypeParameter) + par= SemanticUtil.getNestedType(par, SemanticUtil.REF | SemanticUtil.TDEF); - // 14.8.2.1.3 if (!checkExactMatch) { + // 14.8.2.1-3 CVQualifier cvPar= SemanticUtil.getCVQualifier(par); CVQualifier cvArg= SemanticUtil.getCVQualifier(arg); - if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) { + if (cvPar == cvArg || (isReferenceTypeParameter && cvPar.isAtLeastAsQualifiedAs(cvArg))) { IType pcheck= SemanticUtil.getNestedType(par, CVTYPE); if (!(pcheck instanceof ICPPTemplateParameter)) { par= pcheck; @@ -1584,19 +1585,6 @@ public class CPPTemplates { return deduceTemplateParameterMap(p.getTypeValue(), a.getTypeValue(), map); } - /** - * 14.8.2.1-2 If P is a cv-qualified type, the top level cv-qualifiers of P's type are ignored for type - * deduction. If P is a reference type, the type referred to by P is used for Type deduction. - * - * Also 14.8.2.3-2 where the same logics is used in reverse. - */ - static private IType getParameterTypeForDeduction(IType pType, boolean isReferenceType) { - if (isReferenceType) { - return SemanticUtil.getNestedType(pType, SemanticUtil.REF | SemanticUtil.TDEF); - } - return SemanticUtil.getNestedType(pType, SemanticUtil.TDEF | SemanticUtil.ALLCVQ); - } - /** * 14.8.2.1-2 * if P is not a reference type @@ -2090,7 +2078,7 @@ public class CPPTemplates { } else if (paramType instanceof IArrayType) { paramType = new CPPPointerType(((IArrayType) paramType).getType()); } - Cost cost = Conversions.checkStandardConversionSequence(arg, paramType, false); + Cost cost = Conversions.checkImplicitConversionSequence(true, arg, paramType, UDCMode.noUDC, false); return cost != null && cost.getRank() != Rank.NO_MATCH; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 4e876e22eb2..492290acb1c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -162,7 +162,7 @@ public class Conversions { // We must do a non-reference initialization if (!illformed) { - return nonReferenceConversion(sourceIsLValue, source, cv1T1, udc, isImpliedObject); + return nonReferenceConversion(sourceIsLValue, source, T1, udc, isImpliedObject); } } } @@ -186,16 +186,13 @@ public class Conversions { } } - // [13.3.3.1-6] Subsume cv-qualifications - if (!(uqsource instanceof ICPPClassType) && !(uqtarget instanceof ICPPClassType)) { - source= uqsource; - target= uqtarget; - } - return nonReferenceConversion(sourceIsLValue, source, target, udc, isImpliedObject); + return nonReferenceConversion(sourceIsLValue, source, uqtarget, udc, isImpliedObject); } private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException { - Cost cost= checkStandardConversionSequence(source, target, isImpliedObject); + // [13.3.3.1-6] Subsume cv-qualifications + IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ); + Cost cost= checkStandardConversionSequence(uqSource, target, isImpliedObject); if (cost.getRank() != Rank.NO_MATCH || udc == UDCMode.noUDC) return cost; @@ -330,7 +327,7 @@ public class Conversions { * base conversion does not cause any costs. * @throws DOMException */ - protected static final Cost checkStandardConversionSequence(IType source, IType target, + private static final Cost checkStandardConversionSequence(IType source, IType target, boolean isImplicitThis) throws DOMException { final Cost cost= new Cost(source, target, Rank.IDENTITY); if (lvalue_to_rvalue(cost)) @@ -607,17 +604,6 @@ public class Conversions { } } - // This should actually be done before the conversion is attempted, see for instance 13.3.3.1-6 and 8.5.14. - // However, it does not hurt to do it here either. - IType unqualifiedTarget= getNestedType(target, ALLCVQ | TDEF | REF); - if (!(unqualifiedTarget instanceof ICPPClassType)) { - IType unqualifiedSource= getNestedType(source, ALLCVQ | TDEF | REF); - if (!(unqualifiedSource instanceof ICPPClassType)) { - source= unqualifiedSource; - target= unqualifiedTarget; - } - } - if (source == null || target == null) { cost.setRank(Rank.NO_MATCH); return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 4bd639901f3..23b08505d01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -436,9 +436,10 @@ public class SemanticUtil { return new CPPPointerType(pt); } - //8.3.5-3 - //Any cv-qualifier modifying a parameter type is deleted. - if (forFunctionType && (t instanceof IQualifierType || t instanceof IPointerType)) { + // 8.3.5-3 + // Any cv-qualifier modifying a parameter type is deleted. The parameter type remains + // to be qualified. + if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier._) { return SemanticUtil.getNestedType(t, TDEF | ALLCVQ); } return pt;