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:
parent
480af1ddb1
commit
11a14b7ed3
6 changed files with 53 additions and 6 deletions
|
@ -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;
|
||||||
// };
|
// };
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue