Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorHannes Vogt2019-04-04 16:36:40 -0400
committerNathan Ridge2019-04-19 17:39:30 -0400
commit11a14b7ed3594b61559ed1b62e3080ff1fb04c72 (patch)
tree1afe910b1fd5281844d3946d6cf42111fa2ee371 /core
parent480af1ddb10a8b07466809f6ffb175180011a15c (diff)
downloadorg.eclipse.cdt-11a14b7ed3594b61559ed1b62e3080ff1fb04c72.tar.gz
org.eclipse.cdt-11a14b7ed3594b61559ed1b62e3080ff1fb04c72.tar.xz
org.eclipse.cdt-11a14b7ed3594b61559ed1b62e3080ff1fb04c72.zip
Bug 545756 - Improve EvalBinding.isConstantExpression()
Previously, all variables with an initial value (even non-const) were treated as constant expressions, now only constexpr variables, static const members and global const variables are treated as constant expression. Change-Id: I2acb4033a1f75110302ea25640afb070d025ec2b Signed-off-by: Hannes Vogt <hannes@havogt.de>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java12
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java2
6 files changed, 53 insertions, 6 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index fc1f30c02c..f89cfcd547 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -13031,6 +13031,18 @@ public class AST2CPPTests extends AST2CPPTestBase {
parseAndCheckImplicitNameBindings();
}
+ // struct A {
+ // int x;
+ // };
+ //
+ // template <typename T>
+ // struct B {
+ // A a{sizeof(T)};
+ // };
+ public void testAggregateInitNoNarrowingConversionInDependentConstContext_545756() throws Exception {
+ parseAndCheckImplicitNameBindings();
+ }
+
// struct type{
// int a;
// };
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 1323628a65..c53ccaa951 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
@@ -11282,4 +11282,20 @@ public class AST2TemplateTests extends AST2CPPTestBase {
helper.assertVariableValue("val1", 42);
helper.assertVariableValue("val2", 43);
}
+
+ // template <typename T>
+ // constexpr T id(T a) {
+ // return a;
+ // }
+ //
+ // template <int> struct Waldo {using type = int;};
+ //
+ // const int forty_two = 42;
+ // using const_int_ref = int const&;
+ // const_int_ref ref_forty_two = forty_two;
+ //
+ // Waldo<id(ref_forty_two)>::type a;
+ public void testGlobalConstWorksAsConstExpression_545756() throws Exception {
+ parseAndCheckBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java
index 4999c631b5..9bce0ccd1f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java
@@ -202,7 +202,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
@Override
public boolean isConstexpr() {
- return VariableHelpers.isConstexpr(fDefinition);
+ return VariableHelpers.isConstexpr(fDefinition != null ? fDefinition : fDeclarations[0]);
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
index 64648a5231..fb1190eb5d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
@@ -103,8 +103,10 @@ class AggregateInitialization {
fIndex++;
// [dcl.init.aggr] If the initializer-clause is an expression and a narrowing conversion is
// required to convert the expression, the program is ill-formed.
- if (!(initializer instanceof EvalInitList) && costWithoutElision.isNarrowingConversion()) {
- return Cost.NO_CONVERSION;
+ if (!initializer.isConstantExpression()) {
+ if (!(initializer instanceof EvalInitList) && costWithoutElision.isNarrowingConversion()) {
+ return Cost.NO_CONVERSION;
+ }
}
if (costWithoutElision.compareTo(worstCost) > 0) {
worstCost = costWithoutElision;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
index 6cf8de0818..bec2013b6f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
@@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
@@ -257,8 +258,24 @@ public class EvalBinding extends CPPDependentEvaluation {
}
private boolean computeIsConstantExpression() {
- return fBinding instanceof IEnumerator || fBinding instanceof ICPPFunction
- || (fBinding instanceof IVariable && isConstexprValue(((IVariable) fBinding).getInitialValue()));
+ if (fBinding instanceof IEnumerator || fBinding instanceof ICPPFunction)
+ return true;
+ else if (fBinding instanceof ICPPVariable) {
+ if (!isConstexprValue(((IVariable) fBinding).getInitialValue()))
+ return false;
+ ICPPVariable var = (ICPPVariable) fBinding;
+ if (var.isConstexpr())
+ return true;
+ IType type = SemanticUtil.getNestedType(var.getType(), SemanticUtil.TDEF | SemanticUtil.REF);
+ if (ExpressionTypes.isConst(type)) {
+ if (var instanceof ICPPField) {
+ if (var.isStatic())
+ return true;
+ } else
+ return true;
+ }
+ }
+ return false;
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java
index e882751221..2481dbbcb8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java
@@ -113,7 +113,7 @@ public class ExpressionTypes {
return type;
}
- private static boolean isConst(IType type) {
+ public static boolean isConst(IType type) {
if (type instanceof IQualifierType) {
return ((IQualifierType) type).isConst();
} else if (type instanceof IPointerType) {

Back to the top