This is an archive of the discontinued LLVM Phabricator instance.

[analyzer][StdLibraryFunctionsChecker][NFC] Use Optionals throughout the summary API
ClosedPublic

Authored by martong on Aug 25 2020, 5:06 AM.

Details

Summary

By using optionals, we no longer have to check the validity of types that we
get from a lookup. This way, the definition of the summaries have a declarative
form, there are no superflous conditions in the source code.

Diff Detail

Event Timeline

martong created this revision.Aug 25 2020, 5:06 AM
martong requested review of this revision.Aug 25 2020, 5:06 AM
martong added inline comments.Aug 25 2020, 5:45 AM
clang/test/Analysis/std-c-library-functions-POSIX-lookup.c
15

Probably I should use FileCheck with --allow-empty and with CHECK-EMPTY

martong retitled this revision from [analyzer][StdLibraryFunctionsChecker] Use Optionals throughout the summary API to [analyzer][StdLibraryFunctionsChecker][NFC] Use Optionals throughout the summary API.Aug 25 2020, 5:51 AM
martong updated this revision to Diff 287680.Aug 25 2020, 8:38 AM
  • Use FileCheck in the lit test
balazske added inline comments.Aug 26 2020, 3:12 AM
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
851

Why has this class different layout than GetPointerTy and GetRestrictTy (beneath that here is no ASTContext)? It would be better if all these classes look the same way: First is the operator with QualType, then operator with Optional that calls the other version of the operator. And all of these can be "unnamed" classes?

890–891

Is it better to use ACtx.VoidPtrTy?

1321

It is better to get every type at the start before adding functions, or group the functions and get some types at the start of these groups but mark the groups at least with comments.

martong marked 3 inline comments as done.Aug 26 2020, 4:42 AM
martong added inline comments.
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
851

I'd had the same thoughts before, and was thinking about that maybe a class template would suffice for all these, but then I realized the following:

To make a type const, we don't need the ASTContext, that is the reason of the difference.
However, to make a type restricted or a pointer, we need the ASTContext. This is a legacy non-symmetry from the AST.

And all of these can be "unnamed" classes?

GetPointerTy and GetRestrictTy need the ASTContext in their constructor. And you cannot define a constructor to an unnamed class because you cannot write down the nonexistent name.

890–891

I'd like to use the ACtx as less as possible: just to get the basic types. And from that on we can use our convenience API (GetConstTy, GetPointerTy, etc) to define all of the derived types... and we can do that in a declarative form (like ASTMatchters).
Also, the declarative definition of these types now look the same regardless the type is "derived" from a looked-up type or from a built-in type.

1321

Well, with looked-up types I followed the usual convention to define a variable right before using it. This means that we lookup a type just before we try to add the function which first uses that type.

However, builtin types are defined at the beginning, because they are used very often.

martong marked 3 inline comments as done.Aug 28 2020, 7:20 AM

Ping

balazske added inline comments.Aug 28 2020, 8:26 AM
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
1006

This return of empty vector and possibility of adding empty vector to range constraint is a new thing, probably it is better to check at create of range constraint (or other place) for empty range (in this case the summary could be made invalid)? But this occurs probably never because the matching type (of the max value) should be used at the same function and if the type is there the max value should be too.

1321

I still like it better if all the type variables are created at one place (can be more easy to maintain if order changes and we have one block of types and one of functions) but this is no reason to block this change.

martong updated this revision to Diff 288946.Aug 31 2020, 7:17 AM
  • Add assert in getRanges
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
1006

Alright, I added an assert to RangeConstraint::getRanges:

     const IntRangeVector &getRanges() const {
+      // When using max values for a type, the type normally should be part of
+      // the signature. Thus we must had looked up previously the type. If the
+      // type is not found then the range would be empty, but then the summary
+      // should be invalid too.
+      assert(Args.size() && "Empty range is meaningless");
       return Args;
     }
1321

I see your point, still I'd keep this way, because I this way the functions and the types they use are close to each other in the source.

Just realized. There maybe cases when we'd like to give XMax to an arg constraint, but the type of the arg is Y (X may be a looked up type). One example for such is getchar, where the return type is Int, but we have a range constraint {0, UCharRangeMax}. Consequently, it seems to be better to remove the assert, because we will not be able to handle such cases with looked up types and their max values.

martong updated this revision to Diff 288957.Aug 31 2020, 8:34 AM
  • Revert "Add assert in getRanges"
martong updated this revision to Diff 288958.Aug 31 2020, 8:38 AM
  • Rebase to correct base
martong updated this revision to Diff 289099.Sep 1 2020, 12:58 AM
  • Support empty ranges
balazske accepted this revision.Sep 1 2020, 1:03 AM

Looks good now.

This revision is now accepted and ready to land.Sep 1 2020, 1:03 AM
This revision was landed with ongoing or failed builds.Sep 1 2020, 2:37 AM
This revision was automatically updated to reflect the committed changes.