From 5cd555717bd08a896a25bc5e6d7d95972d2f3f8f Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 26 Nov 2015 14:43:50 -0500 Subject: [PATCH] Bug 479638 - Cache the result of EvalBinding.isConstantExpression() This helps avoid infinite recursion when a variable's initializer references itself. Change-Id: I4667536ebbefd2008afe9003617092a0a5693db0 Signed-off-by: Nathan Ridge --- .../core/internal/checkers/ReturnCheckerTest.java | 12 +++++++++++- .../core/dom/parser/cpp/semantics/EvalBinding.java | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java index cfe7cc23f09..fb3fc76ad8e 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java @@ -417,7 +417,17 @@ public class ReturnCheckerTest extends CheckerTestCase { // } public void testSelfReferencingVariable_452325() throws Exception { // Just check that codan runs without any exceptions being thrown. - checkSampleAbove(); + checkSampleAboveCpp(); + } + + // int bar(int x) { return x; } + // int foo() { // error + // int waldo = bar(waldo); + // if (bar(waldo)); + // } + public void testSelfReferencingVariable_479638() throws Exception { + // Just check that codan runs without any exceptions being thrown. + checkSampleAboveCpp(); } // int foo(int x) { // error 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 ebbe8363833..aea9d30d495 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 @@ -70,8 +70,10 @@ public class EvalBinding extends CPPDependentEvaluation { private IType fType; private boolean fCheckedIsValueDependent; private boolean fIsValueDependent; - private boolean fIsTypeDependent; private boolean fCheckedIsTypeDependent; + private boolean fIsTypeDependent; + private boolean fCheckedIsConstantExpression; + private boolean fIsConstantExpression; public EvalBinding(IBinding binding, IType type, IASTNode pointOfDefinition) { this(binding, type, findEnclosingTemplate(pointOfDefinition)); @@ -240,6 +242,14 @@ public class EvalBinding extends CPPDependentEvaluation { @Override public boolean isConstantExpression(IASTNode point) { + if (!fCheckedIsConstantExpression) { + fCheckedIsConstantExpression = true; + fIsConstantExpression = computeIsConstantExpression(point); + } + return fIsConstantExpression; + } + + private boolean computeIsConstantExpression(IASTNode point) { return fBinding instanceof IEnumerator || fBinding instanceof ICPPFunction || (fBinding instanceof IVariable && isConstexprValue(((IVariable) fBinding).getInitialValue(), point));