================ @@ -121,6 +121,34 @@ struct EvalCallOptions { EvalCallOptions() {} }; +/// Simple control flow statements like `if` can only produce a single two-way +/// state split, so when the analyzer cannot determine the value of the +/// condition, it can assume either of the two options, because the fact that +/// they are in the source code implies that the programmer thought that they +/// are possible (at least under some conditions). +/// (Note that this heuristic is not entirely correct when there are _several_ +/// `if` statements with unmarked logical connections between them, but it's +/// still good enough and the analyzer heavily relies on it.) +/// In contrast with this, a single loop statement can produce multiple state +/// splits, and we cannot always single out safe assumptions where we can say +/// that "the programmer included this loop in the source code, so they clearly +/// thought that this execution path is possible". +/// However, the analyzer wants to explore the code in and after the loop, so +/// it makes assumptions about the loop condition (to get a concrete execution +/// path) even when they are not justified. +/// This function is called by the engine to mark the `State` when it makes an +/// assumption which is "weak". Checkers may use this heuristical mark to +/// discard the result and reduce the amount of false positives. +/// TODO: Instead of just marking these branches for checker-specific handling, +/// we could discard them completely. I suspect that this could eliminate some +/// false positives without suppressing too many true positives, but I didn't +/// have time to measure its effects. +ProgramStateRef recordWeakLoopAssumption(ProgramStateRef State); + +/// Returns true if `recordWeakLoopAssumption()` was called on the execution +/// path which produced `State`. +bool seenWeakLoopAssumption(ProgramStateRef State); ---------------- NagyDonat wrote:
Personally I prefer plain functions instead of `static` methods that are only vaguely connected to a class, but I can move them to `ExprEngine` to follow the precedents. Making `recordWeakLoopAssumption()` private is also a good point -- I'll either do so or just inline its short one-line definition at the few locations where it's called. (I think the transparent `State->set<>` would be clearer than just calling some random method. If we need more complex logic later, we can reintroduce a method like it.) https://github.com/llvm/llvm-project/pull/109804 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits