Bug 479638 - Cache the result of EvalBinding.isConstantExpression()
authorNathan Ridge <zeratul976@hotmail.com>
Thu, 26 Nov 2015 19:43:50 +0000 (14:43 -0500)
committerSergey Prigogin <eclipse.sprigogin@gmail.com>
Thu, 24 Dec 2015 02:25:55 +0000 (18:25 -0800)
This helps avoid infinite recursion when a variable's initializer
references itself.

Change-Id: I4667536ebbefd2008afe9003617092a0a5693db0
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java

index cfe7cc2..fb3fc76 100644 (file)
@@ -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
index ebbe836..aea9d30 100644 (file)
@@ -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));