Skip to content

Commit b94bc49

Browse files
committed
Fix constexpr execution of if statement with static_assert declaration substatement
Stop null dereference in ExecIf when thenClauseExec is null. This happens with throw declaration in thenClause, and ExecIf already allows for null in elseClauseExec so this is a bit more consistent. Null thenClauseExec can be from encountered valid static_assert declaration, handle it during constexpr execution as new special problem type STATIC_ASSERT_FAILED.
1 parent eb0818e commit b94bc49

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

core/org.eclipse.cdt.core/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true
5-
Bundle-Version: 9.2.100.qualifier
5+
Bundle-Version: 9.3.0.qualifier
66
Bundle-Activator: org.eclipse.cdt.core.CCorePlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarationStatement.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
2525
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
2626
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecDeclarationStatement;
27+
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecReturn;
2728

2829
/**
2930
* @author jcamelon
@@ -130,9 +131,15 @@ public void addAttributeSpecifier(IASTAttributeSpecifier attributeSpecifier) {
130131

131132
@Override
132133
public ICPPExecution getExecution() {
133-
if (declaration instanceof ICPPExecutionOwner) {
134-
ICPPExecutionOwner execOwner = (ICPPExecutionOwner) declaration;
135-
return new ExecDeclarationStatement(execOwner.getExecution());
134+
if (declaration instanceof ICPPExecutionOwner execOwner) {
135+
ICPPExecution execution = execOwner.getExecution();
136+
if (execution instanceof ExecReturn) {
137+
// CPPASTStaticAssertionDeclaration simulates error handling via ExecReturn
138+
// with conditional expression which must be executed as is to return problem value
139+
return execution;
140+
} else {
141+
return new ExecDeclarationStatement(execution);
142+
}
136143
}
137144
return null;
138145
}

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTStaticAssertionDeclaration.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,32 @@
1313
*******************************************************************************/
1414
package org.eclipse.cdt.internal.core.dom.parser.cpp;
1515

16+
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
17+
1618
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
1719
import org.eclipse.cdt.core.dom.ast.IASTExpression;
1820
import org.eclipse.cdt.core.dom.ast.IASTNode;
21+
import org.eclipse.cdt.core.dom.ast.IBinding;
22+
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
1923
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
2024
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStaticAssertDeclaration;
2125
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
2226
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
27+
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
28+
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
29+
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
30+
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
31+
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecReturn;
2332

2433
public class CPPASTStaticAssertionDeclaration extends ASTNode
25-
implements ICPPASTStaticAssertDeclaration, IASTAmbiguityParent {
34+
implements ICPPASTStaticAssertDeclaration, IASTAmbiguityParent, ICPPExecutionOwner {
2635

2736
private IASTExpression fCondition;
2837
private final ICPPASTLiteralExpression fMessage;
2938

39+
public static final ICPPEvaluation STATIC_ASSERT_FAILED = new EvalFixed(ProblemType.STATIC_ASSERT_FAILED, PRVALUE,
40+
IntegralValue.STATIC_ASSERT_FAILED_ERROR);
41+
3042
/**
3143
* Constructor for C++17 static_assert with only a condition.
3244
*
@@ -101,4 +113,21 @@ public void replace(IASTNode child, IASTNode other) {
101113
other.setPropertyInParent(child.getPropertyInParent());
102114
}
103115
}
116+
117+
@Override
118+
public ICPPExecution getExecution() {
119+
// Naturally this would be compilation error; simulate executing this statement via return with evaluation problem.
120+
// If no evaluation of condition is available, treat it as unsatisfied condition too.
121+
final ICPPEvaluation conditionExprEval = getCondition() instanceof ICPPASTExpression conditionExpr
122+
? conditionExpr.getEvaluation()
123+
: CPPASTLiteralExpression.INT_ZERO.getEvaluation();
124+
125+
ICPPEvaluation conditionalEval = new EvalConditional(conditionExprEval, null, STATIC_ASSERT_FAILED, false,
126+
false, (IBinding) null);
127+
128+
// ICPPExecution constexprIfExecution = new ExecIf(true, null, conditionExprEval, null, null,
129+
// new ExecReturn(STATIC_ASSERT_FAILED));
130+
131+
return new ExecReturn(conditionalEval);
132+
}
104133
}

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecIf.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ private boolean conditionSatisfied(ActivationRecord record, ConstexprEvaluationC
4949
public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
5050
EvalUtil.executeStatement(initStmtExec, record, context);
5151
if (conditionSatisfied(record, context)) {
52-
return EvalUtil.executeStatement(thenClauseExec, record, context);
53-
} else if (elseClauseExec != null) {
54-
return EvalUtil.executeStatement(elseClauseExec, record, context);
52+
return thenClauseExec != null ? EvalUtil.executeStatement(thenClauseExec, record, context) : null;
53+
} else {
54+
return elseClauseExec != null ? EvalUtil.executeStatement(elseClauseExec, record, context) : null;
5555
}
56-
return null;
5756
}
5857

5958
@Override
@@ -76,12 +75,12 @@ public ICPPExecution instantiate(InstantiationContext context, int maxDepth) {
7675
* might have side effects so it needs to be preserved in the instantiated
7776
* execution even if one of its branch has become null
7877
*/
79-
newThenClauseExec = thenClauseExec.instantiate(context, maxDepth);
78+
newThenClauseExec = thenClauseExec != null ? thenClauseExec.instantiate(context, maxDepth) : null;
8079
} else {
8180
newElseClauseExec = elseClauseExec != null ? elseClauseExec.instantiate(context, maxDepth) : null;
8281
}
8382
} else {
84-
newThenClauseExec = thenClauseExec.instantiate(context, maxDepth);
83+
newThenClauseExec = thenClauseExec != null ? thenClauseExec.instantiate(context, maxDepth) : null;
8584
newElseClauseExec = elseClauseExec != null ? elseClauseExec.instantiate(context, maxDepth) : null;
8685
}
8786

0 commit comments

Comments
 (0)