Hi, It may not be worth altering at this point, but it seems like it would leave less bugs open if all the constraints go in as "closed" ranges and all evals are translated to closed intervals. So, if (idx > 0) and if (idx >= 1) are the same constraint. I know this won't be an option for eventual float support, but that is a different can of worms. For integers, you can fix it at those entry points and then all other subroutines can ignore the issue of open or closed ranges.
I fully understand the eye glaze and did not want to have to write it that way. I am thinking if there is a cleaner way to do it. Anyway, that is why I put a comment in each case to derive the result. This issue of "sides of the condition" and "inverted operator" as you call it in some places is a recurring theme. It is especially irritating when we lose commutativity, as we do with MINUS. Adding logic in my subroutine for MULT or DIV is not hard, handling overflow is a bit more involved. At the very least, we would need to know what the max or min of a particular variable is, which might be in the type tree. We would also need to define how we want to handle the issue. The problem is (and I have been thinking about this a lot in terms of constraint merging), there are currently no "or constraints," which would be helpful in merging too. So for overflow, when you have something like if (idx > 0) { idx += num; __analyzer_eval(idx > num); } you have gone from a single constraint (idx > 0), to an "or condition" (idx > num || idx < MIN_INT + num). The only solution now, other than ignoring overflow as a bug that is tolerated, is to just pass it off as unhandled (and therefore UNKNOWN). Perhaps you may want to add overflow as one of your analyzer warnings if it cannot be ruled out? I did try to run a test with a simple || in the condition before just to see what would happen, and as you probably know it is not handled at all. I did not watch in gdb, but it is obvious from constraint-manager.cc that there is nothing to handle it. I think I actually did an __analyzer_eval() of the same || condition verbatim that was in the if() conditional and still got an UNKNOWN. It is a pretty intrusive change to add logic for that, which is why I have not done any work on it yet. Without the concept of "or" I don't see how we could handle overflow, but maybe you don't really want to handle it anyway, but rather just emit a warning if it might be considered poor practice to rely on something that is technically machine dependent anyway.