From 2734b7ae8295dd4dde0d4383b2bcf7dc708a072a Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Sun, 19 May 2019 20:02:34 +1000 Subject: Bug 545040 - make array size inference work with initializer lists Resolution for DR1591 clarified that initializer list size could be used to deduce array size (if it is a template parameter). Change-Id: Ic3617e31b125083f1205f91383eb27f5e5a29041 Signed-off-by: Davin McCall --- .../cpp/semantics/TemplateArgumentDeduction.java | 65 +++++++++++++++------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'core/org.eclipse.cdt.core') diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 9cf6aee19ac..1ceb1694fc9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -148,7 +148,20 @@ public class TemplateArgumentDeduction { par = SemanticUtil.getNestedType(par, TDEF | REF | CVTYPE); // Check if this is a deduced context. - IType inner = Conversions.getInitListType(par); + IType inner = null; + if (par instanceof IArrayType) { + // As per DR1591, if an initializer list is given as an argument for parameter type P[N], + // we can deduce N from the size of the initializer list (and potentially deduce P from + // the elements in the list). + inner = ((IArrayType) par).getType(); + IValue as = IntegralValue + .create(((InitializerListType) arg).getEvaluation().getClauses().length); + IValue ps = ((IArrayType) par).getSize(); + if (!deduct.fromArraySize(ps, as)) + return false; + } else { + inner = Conversions.getInitListType(par); + } if (inner != null) { final EvalInitList eval = ((InitializerListType) arg).getEvaluation(); for (ICPPEvaluation clause : eval.getClauses()) { @@ -853,6 +866,35 @@ public class TemplateArgumentDeduction { && fromType(p.getTypeValue(), a.getTypeValue(), false, true)); } + /** + * Deduce a parameter array size from an argument array size. + * @param ps the parameter size (may refer to template parameter) + * @param as the argument array or initializer list size + * @return false if deduction encountered an error, true otherwise + */ + private boolean fromArraySize(IValue ps, IValue as) { + if (as != ps) { + if (as == null || ps == null) + return false; + + int parID = IntegralValue.isTemplateParameter(ps); + if (parID >= 0) { + ICPPTemplateArgument old = fDeducedArgs.getArgument(parID, fPackOffset); + if (old == null) { + if (!deduce(parID, new CPPTemplateNonTypeArgument(as, new TypeOfValueDeducedFromArraySize()))) { + return false; + } + } else if (!as.equals(old.getNonTypeValue())) { + return false; + } + } else if (!as.equals(ps)) { + return false; + } + } + + return true; + } + private boolean fromType(IType p, IType a, boolean allowCVQConversion, boolean verifyNonDeduced) throws DOMException { IType originalArgType = a; @@ -910,25 +952,8 @@ public class TemplateArgumentDeduction { IArrayType pa = (IArrayType) p; IValue as = aa.getSize(); IValue ps = pa.getSize(); - if (as != ps) { - if (as == null || ps == null) - return false; - - int parID = IntegralValue.isTemplateParameter(ps); - if (parID >= 0) { - ICPPTemplateArgument old = fDeducedArgs.getArgument(parID, fPackOffset); - if (old == null) { - if (!deduce(parID, - new CPPTemplateNonTypeArgument(as, new TypeOfValueDeducedFromArraySize()))) { - return false; - } - } else if (!as.equals(old.getNonTypeValue())) { - return false; - } - } else if (!as.equals(as)) { - return false; - } - } + if (!fromArraySize(ps, as)) + return false; p = pa.getType(); a = aa.getType(); } else if (p instanceof IQualifierType) { -- cgit v1.2.3