1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 22:22:11 +02:00

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>
This commit is contained in:
Hannes Vogt 2019-04-04 22:36:40 +02:00 committed by Nathan Ridge
parent 480af1ddb1
commit 11a14b7ed3
6 changed files with 53 additions and 6 deletions

View file

@ -13031,6 +13031,18 @@ public class AST2CPPTests extends AST2CPPTestBase {
parseAndCheckImplicitNameBindings(); parseAndCheckImplicitNameBindings();
} }
// struct A {
// int x;
// };
//
// template <typename T>
// struct B {
// A a{sizeof(T)};
// };
public void testAggregateInitNoNarrowingConversionInDependentConstContext_545756() throws Exception {
parseAndCheckImplicitNameBindings();
}
// struct type{ // struct type{
// int a; // int a;
// }; // };

View file

@ -11282,4 +11282,20 @@ public class AST2TemplateTests extends AST2CPPTestBase {
helper.assertVariableValue("val1", 42); helper.assertVariableValue("val1", 42);
helper.assertVariableValue("val2", 43); 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();
}
} }

View file

@ -202,7 +202,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
@Override @Override
public boolean isConstexpr() { public boolean isConstexpr() {
return VariableHelpers.isConstexpr(fDefinition); return VariableHelpers.isConstexpr(fDefinition != null ? fDefinition : fDeclarations[0]);
} }
@Override @Override

View file

@ -103,8 +103,10 @@ class AggregateInitialization {
fIndex++; fIndex++;
// [dcl.init.aggr] If the initializer-clause is an expression and a narrowing conversion is // [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. // required to convert the expression, the program is ill-formed.
if (!(initializer instanceof EvalInitList) && costWithoutElision.isNarrowingConversion()) { if (!initializer.isConstantExpression()) {
return Cost.NO_CONVERSION; if (!(initializer instanceof EvalInitList) && costWithoutElision.isNarrowingConversion()) {
return Cost.NO_CONVERSION;
}
} }
if (costWithoutElision.compareTo(worstCost) > 0) { if (costWithoutElision.compareTo(worstCost) > 0) {
worstCost = costWithoutElision; worstCost = costWithoutElision;

View file

@ -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.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
@ -257,8 +258,24 @@ public class EvalBinding extends CPPDependentEvaluation {
} }
private boolean computeIsConstantExpression() { private boolean computeIsConstantExpression() {
return fBinding instanceof IEnumerator || fBinding instanceof ICPPFunction if (fBinding instanceof IEnumerator || fBinding instanceof ICPPFunction)
|| (fBinding instanceof IVariable && isConstexprValue(((IVariable) fBinding).getInitialValue())); 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 @Override

View file

@ -113,7 +113,7 @@ public class ExpressionTypes {
return type; return type;
} }
private static boolean isConst(IType type) { public static boolean isConst(IType type) {
if (type instanceof IQualifierType) { if (type instanceof IQualifierType) {
return ((IQualifierType) type).isConst(); return ((IQualifierType) type).isConst();
} else if (type instanceof IPointerType) { } else if (type instanceof IPointerType) {