File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -59,6 +59,8 @@ namespace {
5959 Analyzer::Terminate terminate = Analyzer::Terminate::None;
6060 std::vector<Token*> loopEnds;
6161 int branchCount = 0 ;
62+ // Nested condition-fork depth on this lineage (copied by fork()); bounds the fan-out.
63+ int forkDepth = 0 ;
6264
6365 Progress Break (Analyzer::Terminate t = Analyzer::Terminate::None) {
6466 if ((!analyzeOnly || analyzeTerminate) && t != Analyzer::Terminate::None)
@@ -796,8 +798,14 @@ namespace {
796798 if (thenBranch.hasGoto () || elseBranch.hasGoto ()) {
797799 return Break (Analyzer::Terminate::Bail);
798800 }
799- if (pThen != Progress::Break && !thenBranch.isEscape ())
801+ // Carry the then-fork forward; past the limit only the linear main path
802+ // continues (no branch skipped). Negative == unlimited.
803+ const int forkDepthLimit = settings.vfOptions .maxForwardConditionForkDepth ;
804+ if (pThen != Progress::Break && !thenBranch.isEscape () &&
805+ (forkDepthLimit < 0 || forkDepth < forkDepthLimit)) {
806+ ft.forkDepth = forkDepth + 1 ;
800807 ft.updateRange (thenBranch.endBlock , end, depth - 1 );
808+ }
801809 if (pElse == Progress::Break)
802810 return Break ();
803811 }
Original file line number Diff line number Diff line change @@ -335,6 +335,7 @@ void Settings::setCheckLevel(CheckLevel level)
335335 vfOptions.maxIfCount = 100 ;
336336 vfOptions.doConditionExpressionAnalysis = false ;
337337 vfOptions.maxForwardBranches = 4 ;
338+ vfOptions.maxForwardConditionForkDepth = 0 ;
338339 vfOptions.maxIterations = 1 ;
339340 }
340341 else if (level == CheckLevel::normal) {
@@ -344,6 +345,7 @@ void Settings::setCheckLevel(CheckLevel level)
344345 vfOptions.maxIfCount = 100 ;
345346 vfOptions.doConditionExpressionAnalysis = false ;
346347 vfOptions.maxForwardBranches = 4 ;
348+ vfOptions.maxForwardConditionForkDepth = 1 ;
347349 }
348350 else if (level == CheckLevel::exhaustive) {
349351 // Checking can take a little while. ~ 10 times slower than normal analysis is OK.
@@ -352,6 +354,7 @@ void Settings::setCheckLevel(CheckLevel level)
352354 vfOptions.maxSubFunctionArgs = 256 ;
353355 vfOptions.doConditionExpressionAnalysis = true ;
354356 vfOptions.maxForwardBranches = -1 ;
357+ vfOptions.maxForwardConditionForkDepth = 4 ;
355358 }
356359}
357360
Original file line number Diff line number Diff line change @@ -512,6 +512,12 @@ class CPPCHECKLIB WARN_UNUSED Settings {
512512 /* * @brief Maximum performed forward branches */
513513 int maxForwardBranches = -1 ;
514514
515+ /* * @brief Maximum depth of nested condition-fork continuations in the forward analyzer.
516+ Bounds the exponential fan-out of carrying condition state forward at exhaustive level (where
517+ maxForwardBranches is unlimited); past it the forward analysis continues on a single linear path
518+ without skipping any branch. 0 disables forking (linear); a negative value means unlimited. */
519+ int maxForwardConditionForkDepth = 4 ;
520+
515521 /* * @brief Maximum performed alignof recursion */
516522 int maxAlignOfRecursion = 100 ;
517523
You can’t perform that action at this time.
0 commit comments