steakhal wrote: > I verified that the `BranchCondition` callback does not react to `switch` > statements because although they perform branching, they don't have a branch > _condition_ like the other statements.
That's correct. I also documented this in the CheckerDocumentation of `checkBranchCondition` [here](https://clang.llvm.org/doxygen/classclang_1_1ento_1_1CheckerDocumentation.html#acec0e845a9dce2fac06bf3b1e136aff7): > - ternary operators (?:), gnu conditionals, gnu choose expressions > Interestingly, switch statements don't seem to trigger BranchCondition. > Perhaps I could switch to using a `BlockEntrance` callback because I'm pretty > confident that it does react to blocks entered via a `switch` statement. > However there are also several other differences between the two callbacks: `BlockEntrance` would be called for all CFG block transitions, yes. > 1. `BlockEntrance` is activated by the transitions from the imaginary "entry" > blocks of inlined functions to the first "real" block; > 2. `BlockEntrance` is activated by the transitions from the final block of a > function to the imaginary "exit" block; > 3. `BlockEntrance` is activated at points where two or more paths (e.g. the > `if` and the `else` branch) are merged; > 4. I strongly suspect that `BlockEntrance` is activated when execution enters > the body of a `do { ... } while (...)` loop; > 5. `BlockEntrance` may be executed when the execution passes over a goto > label (which is e.g. referenced by a `goto` later in the body of the code). > 6. `BlockEntrance` may be executed when the execution encounters C++ > exception handling logic. > > For this checker difference No.3 is irrelevant (because it ignores everything > after encountering a path split, and path merging cannot happen without a > path split) and No.6 is either helpful or irrelevant (exceptions are real > branching points, but they rarely appear in C-style variadic functions), but > the No.1-2 (the imaginary entry/exit) must be handled somehow and No.4-5. > (do-while, goto) are also drawbacks of the `BlockEntrance` callback for this > usecase (although they are rare, so it is forgivable if the checker produces > false negatives on them). > > As another approach, I also thought about modifying the engine to let it > trigger the `BranchCondition` callbacks upon entering `switch` statements. It > would be feasible to implement this because there are very few checkers that > use `BranchCondition` – but I feel that it would be against the "real > meaning" of that callback. > > @steakhal (or anybody else familiar with `BlockEntrance`) > > * What do you think about this situation? > * Should I use the `BlockEntrance` callback or do you see another approach? I have no strong preference for using `BlockEntrance`. The `BranchCondition` should probably cover switches. If possible, `BlockEntrance` should be avoided as it gets triggered really frequently. > * If I use `BlockEntrance` do you know a straightforward way to filter out > the unwanted transitions (especially the ones with the imaginary "entry" or > "exit" nodes)? It's really easy to ignore those transitions. Get the Exit and Entry nodes of your CFG and check if the `clang::BlockEntrance` `getBlock()` and `getPreviousBlock()` refers to any of those. If so, bail. The idea of the callback was to be completely truthful to how the exploded graph is built. If that inserts a BlockEntrance, it should trigger the callback. That's it. I'm not completely up to date how exceptions are handled in CSA, but they are not handled in any special way for this callback for sure. https://github.com/llvm/llvm-project/pull/175602 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
