This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Generalize bitwise OR rules for ranges
ClosedPublic

Authored by vsavchenko on May 4 2020, 9:49 AM.

Details

Summary

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.

Diff Detail

Event Timeline

vsavchenko created this revision.May 4 2020, 9:49 AM
Herald added a project: Restricted Project. ยท View Herald TranscriptMay 4 2020, 9:49 AM
xazax.hun added inline comments.May 4 2020, 10:36 AM
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?
Do we want to model a cast in the code somewhere?
If so, I think this is more like a workaround and in the future we would need an explicit way to represent those cast operations. It might be worth to have a TODO.

vsavchenko marked 3 inline comments as done.May 4 2020, 2:19 PM
vsavchenko added inline comments.
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.

ASDenysPetrov added inline comments.May 4 2020, 3:22 PM
clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
77

Be aware as D77792 also implements such a method.

NoQ accepted this revision.May 5 2020, 6:03 AM

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.

This revision is now accepted and ready to land.May 5 2020, 6:03 AM

Fix few things here and there

Fix clang-format issue

Fix a bug with double expressions withing integer expressions

Harbormaster completed remote builds in B57068: Diff 264615.
This revision was automatically updated to reflect the committed changes.