2626import com .google .common .collect .ImmutableSet ;
2727import com .google .common .collect .Iterables ;
2828import com .google .common .collect .Lists ;
29+
2930import org .slf4j .Logger ;
3031import org .slf4j .LoggerFactory ;
3132import org .sonar .java .cfg .CFG ;
@@ -81,6 +82,7 @@ public class ExplodedGraphWalker extends BaseTreeVisitor {
8182 * Arbitrary number to limit symbolic execution.
8283 */
8384 private static final int MAX_STEPS = 10000 ;
85+ public static final int MAX_NESTED_BOOLEAN_STATES = 10000 ;
8486 private static final Logger LOG = LoggerFactory .getLogger (ExplodedGraphWalker .class );
8587 private static final Set <String > THIS_SUPER = ImmutableSet .of ("this" , "super" );
8688
@@ -112,6 +114,13 @@ public static class MaximumStepsReachedException extends RuntimeException {
112114 public MaximumStepsReachedException (String s ) {
113115 super (s );
114116 }
117+
118+ public MaximumStepsReachedException (String s , TooManyNestedBooleanStatesException e ) {
119+ super (s , e );
120+ }
121+ }
122+
123+ public static class TooManyNestedBooleanStatesException extends RuntimeException {
115124 }
116125
117126 public ExplodedGraphWalker (JavaFileScannerContext context ) {
@@ -163,20 +172,25 @@ private void execute(MethodTree tree) {
163172 LOG .debug ("End of potential path reached!" );
164173 continue ;
165174 }
166- if (programPosition .i < programPosition .block .elements ().size ()) {
167- // process block element
168- visit (programPosition .block .elements ().get (programPosition .i ), programPosition .block .terminator ());
169- } else if (programPosition .block .terminator () == null ) {
170- // process block exit, which is unconditional jump such as goto-statement or return-statement
171- handleBlockExit (programPosition );
172- } else if (programPosition .i == programPosition .block .elements ().size ()) {
173- // process block exist, which is conditional jump such as if-statement
174- checkerDispatcher .executeCheckPostStatement (programPosition .block .terminator ());
175- } else {
176- // process branch
177- // process block exist, which is conditional jump such as if-statement
178- checkerDispatcher .executeCheckPreStatement (programPosition .block .terminator ());
179- handleBlockExit (programPosition );
175+ try {
176+ if (programPosition .i < programPosition .block .elements ().size ()) {
177+ // process block element
178+ visit (programPosition .block .elements ().get (programPosition .i ), programPosition .block .terminator ());
179+ } else if (programPosition .block .terminator () == null ) {
180+ // process block exit, which is unconditional jump such as goto-statement or return-statement
181+ handleBlockExit (programPosition );
182+ } else if (programPosition .i == programPosition .block .elements ().size ()) {
183+ // process block exist, which is conditional jump such as if-statement
184+ checkerDispatcher .executeCheckPostStatement (programPosition .block .terminator ());
185+ } else {
186+ // process branch
187+ // process block exist, which is conditional jump such as if-statement
188+ checkerDispatcher .executeCheckPreStatement (programPosition .block .terminator ());
189+ handleBlockExit (programPosition );
190+ }
191+ } catch (ExplodedGraphWalker .TooManyNestedBooleanStatesException e ) {
192+ throw new MaximumStepsReachedException (
193+ "reached maximum number of " + MAX_NESTED_BOOLEAN_STATES + " branched states for method " + tree .simpleName ().name () + " in class " + tree .symbol ().owner ().name (), e );
180194 }
181195 }
182196
@@ -609,7 +623,6 @@ public void enqueue(ExplodedGraph.ProgramPoint programPoint, ProgramState progra
609623 }
610624
611625 public void enqueue (ExplodedGraph .ProgramPoint programPoint , ProgramState programState , boolean exitPath ) {
612- checkMaxStepsWhileEnqueuing ();
613626 int nbOfExecution = programState .numberOfTimeVisited (programPoint );
614627 if (nbOfExecution > MAX_EXEC_PROGRAM_POINT ) {
615628 debugPrint (programState );
@@ -625,13 +638,6 @@ public void enqueue(ExplodedGraph.ProgramPoint programPoint, ProgramState progra
625638 workList .addFirst (cachedNode );
626639 }
627640
628- private void checkMaxStepsWhileEnqueuing () {
629- if (steps + workList .size () + 1 > MAX_STEPS ) {
630- throw new MaximumStepsReachedException ("reached limit of " + MAX_STEPS +
631- " steps for method " + methodTree .simpleName ().name () + " in class " + methodTree .symbol ().owner ().name () +" while enqueuing program states." );
632- }
633- }
634-
635641 private void checkExplodedGraphTooBig (ProgramState programState ) {
636642 // Arbitrary formula to avoid out of memory errors
637643 if (steps + workList .size () > MAX_STEPS / 2 && programState .constraintsSize () > 75 ) {
0 commit comments