Previously the current solver started reasoning about bitwise OR
expressions only when one of the operands is a constant. However,
very similar logic could be applied to ranges. This commit addresses
this shortcoming. Additionally, it refines how we deal with negative
operands.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Here is a little proof I've put together (using Z3): https://gist.github.com/SavchenkoValeriy/9ad6ca72e7420fd5612e618187bd4f76
clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | ||
---|---|---|
77 | Yeah, this is quite unfortunate. But you might end up calling this a lot for bitwise operations. I wonder if it is worth to solve this problem before commiting this patch. I do not insist though. | |
450 | Is roughen part of a nomenclature? If not, what about something like cover? | |
480 | Why do we need this conversion? |
clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | ||
---|---|---|
77 | I was even thinking about fixing it myself, this shouldn't be very hard, Also addition of lower_bound and upper_bound can really help implementing Includes for RangeSet. | |
450 | Yeah ๐ I spend quite some time thinking about a proper name for that one. It is used to be coarsen (yep, yuck!), but I don't really feel "cover" either. Mb something like "unify" will work? What do you think? | |
480 | Those ranges that we inferred have nothing to do with upper operations. I mean, in theory, VisitBinaryOperator can take care of conversions, but I don't know how it can be done in the most generic way. In this particular situation, we really care that From and To don't change signs or something like that after conversion, but for other operators it might be not so important. Answering the question of why we even need those, putting it simple - there is no other way, this is how APSInt works, couldn't do anything with values of different types (e.g. comparison). I am totally on board with you on the inconvenience of the whole thing. Every implementer of the Visit* method should take care of conversions on their own. I would say that SValBuilder adding special symbolic values for this kind of casts, can be a solution. |
Math looks good to me :)
clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | ||
---|---|---|
450 | Well, this is basically a one-dimensional convex hull... But i do think that something like fillGaps() would be easier to understand. | |
480 | Yeah i think this is correct. This is exactly how our symbolic expressions aren't type-safe: expression of type T corresponds to result of operations during which operand symbols were promoted to T. |
Yeah, this is quite unfortunate. But you might end up calling this a lot for bitwise operations. I wonder if it is worth to solve this problem before commiting this patch. I do not insist though.