From d07b74f31a830548d55c570bb945a49010aaf9f0 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 21 Mar 2016 16:33:23 -0700 Subject: [PATCH] Bug 489987 - Name resolution problem with static constexpr method Change-Id: Ib1ec66f3c4d250112a606482a8c97a593fb0bfce --- .../parser/tests/ast2/AST2TemplateTests.java | 29 +++++++++++++++++++ .../parser/cpp/semantics/CPPEvaluation.java | 23 +++++++++++++-- .../cpp/semantics/EvalFunctionCall.java | 11 ++++--- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 1a635922c7d..a28792b6c10 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -7480,6 +7480,35 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // struct C {}; + // + // template + // struct C { + // typedef T type; + // }; + // + // template + // struct B { + // static constexpr bool b() { + // return true; + // } + // }; + // + // struct A { + // template ::b()>::type> + // A(T v); + // }; + // + // void waldo(A p); + // + // void test(int x) { + // waldo(x); + // } + public void testConstexprMethod_489987() throws Exception { + parseAndCheckBindings(); + } + // template // struct is_convertible { // static char check(From); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 07d65582dd9..62f6c1d0732 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -92,9 +92,28 @@ public abstract class CPPEvaluation implements ICPPEvaluation { return false; } + /** + * Checks if all evaluations contained in the given array are constant expressions. + * + * @param evaluations the evaluations to check + * @param point the point of instantiation + */ protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, IASTNode point) { - for (ICPPEvaluation eval : evaluations) { - if (!eval.isConstantExpression(point)) { + return areAllConstantExpressions(evaluations, 0, evaluations.length, point); + } + + /** + * Checks if all evaluations contained in a range of the given array are constant expressions. + * + * @param evaluations the evaluations to check + * @param from the initial index of the range to be checked, inclusive + * @param to the final index of the range to be checked, exclusive + * @param point the point of instantiation + */ + protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, int from, int to, + IASTNode point) { + for (int i = from; i < to; i++) { + if (!evaluations[i].isConstantExpression(point)) { return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 096b7421c2d..ce95e5ecfd9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -217,15 +217,18 @@ public class EvalFunctionCall extends CPPDependentEvaluation { return this; // If the arguments are not all constant expressions, there is // no point trying to substitute them into the return expression. - if (!areAllConstantExpressions(fArguments, context.getPoint())) + if (!areAllConstantExpressions(fArguments, 1, fArguments.length, context.getPoint())) return this; ICPPFunction function = getOverload(context.getPoint()); if (function == null) { + IBinding binding = null; if (fArguments[0] instanceof EvalBinding) { - IBinding binding = ((EvalBinding) fArguments[0]).getBinding(); - if (binding instanceof ICPPFunction) - function = (ICPPFunction) binding; + binding = ((EvalBinding) fArguments[0]).getBinding(); + } else if (fArguments[0] instanceof EvalMemberAccess) { + binding = ((EvalMemberAccess) fArguments[0]).getMember(); } + if (binding instanceof ICPPFunction) + function = (ICPPFunction) binding; } if (function == null) return this;