This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] StdLibraryFunctionsChecker: Add LazyRanges to support type dependent Max
AbandonedPublic

Authored by martong on May 5 2020, 9:43 AM.

Details

Summary

Some functions uses a platform dependent ssize_t (e.g. read). Currently, we
provide different summaries for the possible variants depending on the
canonical type of ssize_t (int, long, long long). In this patch we get rid of
this burden, thus making the administration of summaries easier. The newly
introduced LazyRangeInt is a union of a RangeInt and a function pointer. We
get the ranges lazily. By the time we need the ranges we already have a
concrete FunctionDecl set for the summary. When a function pointer is used
amongst the range values then we evaluate the function. This way we can get a
type dependent Max value and instead of providing 3 summaries to read we can
provide only one.

Diff Detail

Event Timeline

martong created this revision.May 5 2020, 9:43 AM

I am a bit unsure what the purpose of these Max summaries are? As far as I understand the Max represents the largest value for the type of the formal parameter.

Do we really ever need to specify this in a summary? Isn't it always an error to pass a value that is larger than the formal's type can represent?

If the answer is yes, I think we should have a separate checker for catching those overflows. If the answer is no, we might want to express a simpler summary, something like cannot overflow on argument X.

What do you think?

I am a bit unsure what the purpose of these Max summaries are? As far as I understand the Max represents the largest value for the type of the formal parameter.

Yes, that's right. The tricky part here is that, when we write the summary we may not know what is going to be the type. In some cases (e.g. read with ssize_t) it turns out only after we looked up the FunctionDecl.

Isn't it always an error to pass a value that is larger than the formal's type can represent?
If the answer is yes, I think we should have a separate checker for catching those overflows. If the answer is no, we might want to express a simpler summary, something like cannot overflow on argument X.

The answer is yes. And yep we could have such a checker. But please read on.

Do we really ever need to specify this in a summary?

It would be possible to have a different DSL for describing the summaries. Now, the RangeConstraint requires a list of ranges, but that's just some technical detail. So, instead of

.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, Max)))

we could have

.ArgConstraint(ArgumentCondition(0, WithinRange, GreaterThanOrEqTo(0)))

. In this case, however, GreaterThanOrEqTo would return a range(0, Max). And Max still would be something that we can evaluate only lazily (once we have the FunctionDecl).
I prefer the explicit Range(0, Max) notion, because then the range is seen immediately.

martong abandoned this revision.Jun 22 2020, 2:36 AM

Since D80016 we are able to look up types in the TU, so we can get the maximum value from the found type.