This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
ClosedPublic

Authored by martong on Feb 24 2020, 9:56 AM.

Diff Detail

Event Timeline

martong created this revision.Feb 24 2020, 9:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 24 2020, 9:56 AM
steakhal added inline comments.Mar 3 2020, 9:22 AM
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
719

Two lines below you are using the {0U} initialization syntax, and here the simple constructor call syntax.
Shouldn't we pick one?

Szelethus added inline comments.Mar 11 2020, 8:24 AM
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
188

What does this do? Is it ever used in the patch?

NoQ accepted this revision.Mar 15 2020, 9:54 PM

This is basically a shorthand for "outside [0, 0]", right? I don't mind ^.^

This revision is now accepted and ready to land.Mar 15 2020, 9:54 PM
balazske added inline comments.Mar 16 2020, 9:51 AM
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
202

Is Tmp better name?

clang/test/Analysis/std-c-library-functions-arg-constraints.c
76

One difficulty is that fread can work if the buf is 0 and count is 0 too. There is for sure code that uses this feature.

martong marked 6 inline comments as done.Mar 18 2020, 6:00 AM
martong added inline comments.
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
188

Yes, it is used. We use it in apply the value is passed to assume.
And in negate we flip the value.

202

Absolutely, yes, I should avoid lower case variables, will rename.

719

Yes, definitely. I think I am going to use brace initialization syntax everywhere.

clang/test/Analysis/std-c-library-functions-arg-constraints.c
76

My understanding is that in case of fread, if buf is 0 then that is an undefined behavior.

In the section in C11 describing the use of library functions (§7.1.4) it is stated that:

If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined. If a function argument is described as being an array, the pointer actually passed to the function shall have a value such that all address computations and accesses to objects (that would be valid if the pointer did point to the first element of such an array) are in fact valid.

I've found more details in this StackOverflow post:
https://stackoverflow.com/questions/51779960/is-it-safe-to-fread-0-bytes-into-a-null-pointer

Also note that a sane libc implementation would not dereference buf if size is 0, but we may not rely on these implementation details, that is why this is declared as undefined behavior in the standard.

Szelethus accepted this revision.EditedMar 18 2020, 7:12 AM

LGTM! Please address the nits before commiting, but there is no need for another round of reviews. :)

edit: from my end, that is.

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
188

Forgot my eyes in the office. Woops. I would still prefer a line of comment here :)

930–931

Not super relevant to this specific revision, but shouldn't we leave these to StreamChecker?

martong updated this revision to Diff 251674.Mar 20 2020, 9:21 AM
martong marked 9 inline comments as done.
  • Use report/bugpath verify prefixes in test
  • Address review nits
In D75063#1923780, @NoQ wrote:

This is basically a shorthand for "outside [0, 0]", right? I don't mind ^.^

Yeah, and my first attempt was exactly to implement this with ranges. However, it failed when I realized that we cannot cast a pointer to NonLoc, so the already written RangeConstraint::apply* functions could not work (I would have to add another branch for handling Loc kind of SVals for the pointer case).

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
188

Ok, I added a comment about its role.

719

Finally I ended up with the parens. :)

930–931

Well, yeah we could remove fread and fwrite from the summaries entirely at some point, but that will require changing the test files here.

This revision was automatically updated to reflect the committed changes.