Page MenuHomePhabricator

[analyzer] StdLibraryFunctionsChecker: Associate summaries to FunctionDecls
ClosedPublic

Authored by martong on Apr 7 2020, 5:05 AM.

Details

Summary

Currently we map function summaries to names (i.e. strings). We can
associate more summaries with different signatures to one name, this way
we support overloading. During a call event we check whether the
signature of the summary matches the signature of the callee and we
apply the summary only in that case.

In this patch we change this mapping to associate a summary to a
FunctionDecl. We do lookup operations when the summary map is
initialized. We lookup the given name and we match the signature of the
given summary against the lookup results. If the summary matches the
FunctionDecl (got from the lookup result) then we add that to the
summary map. During a call event we compare FunctionDecl pointers.
Advantages of this new refactor:

  • Cleaner mapping and structure for the checker.
  • Possibly way more efficient handling of call events.
  • A summary is added only if that is relevant for the given TU.
  • We can get the concrete FunctionDecl by the time when we create the summary, this opens up possibilities of further sanity checks regarding the summary cases and argument constraints.
  • Opens up to future work when we'd like to store summaries from IR to a FunctionDecl (or from the Attributor results of the given FunctionDecl).

Note, we cannot support old C functions without prototypes.

Diff Detail

Unit TestsFailed

TimeTest
4,660 mslldb-api.functionalities/thread/concurrent_events::Unknown Unit Message ("")
Script: -- /usr/bin/python /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/lldb/test/API/dotest.py --arch x86_64 -s /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-traces -S nm -u CXXFLAGS -u CFLAGS --env ARCHIVER=/usr/bin/ar --env OBJCOPY=/usr/bin/objcopy --env LLVM_LIBS_DIR=/mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./lib --build-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex --lldb-module-cache-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/lldb --compiler /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/clang --dsymutil /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/dsymutil --filecheck /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/FileCheck --lldb-libs-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./lib /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/lldb/test/API/functionalities/thread/concurrent_events -p TestConcurrentCrashWithWatchpointBreakpointSignal.py
77,920 mslldb-api.tools/lldb-server::Unknown Unit Message ("")
Script: -- /usr/bin/python /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/lldb/test/API/dotest.py --arch x86_64 -s /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-traces -S nm -u CXXFLAGS -u CFLAGS --env ARCHIVER=/usr/bin/ar --env OBJCOPY=/usr/bin/objcopy --env LLVM_LIBS_DIR=/mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./lib --build-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex --lldb-module-cache-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/lldb --compiler /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/clang --dsymutil /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/dsymutil --filecheck /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./bin/FileCheck --lldb-libs-dir /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/build/./lib /mnt/disks/ssd0/agent/workspace/BETA_amd64_debian_testing_clang8/llvm-project/lldb/test/API/tools/lldb-server -p TestLldbGdbServer.py
150 mslldb-unit.Host/_/HostTests::Unknown Unit Message ("")
Note: Google Test filter = ConnectionFileDescriptorTest.TCPGetURIv6 [==========] Running 1 test from 1 test case. [----------] Global test environment set-up.

Event Timeline

martong created this revision.Apr 7 2020, 5:05 AM
martong marked an inline comment as done.Apr 7 2020, 5:12 AM
martong added inline comments.
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
570

Ups, this function is unused I'll remove.

martong marked an inline comment as not done.Apr 7 2020, 5:13 AM
Szelethus accepted this revision.EditedApr 8 2020, 5:53 AM

LGTM! Its always a joy to see you do C++. I suspect your change made compiler errors a bit nicer as well, so you don't get one giant "Well, this huuuuuge single argument doesn't match any of the assignment operators".

We don't have any function names that have multiple summaries just yet, correct? Also, this change is NFC, right? Could you make a tag about that to the revision title in the future?

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

How about FSMIt? :^)

This revision is now accepted and ready to land.Apr 8 2020, 5:53 AM

Also, if you gave a bit of time for anyone else to have a say, that might be nice. :)

NoQ added a comment.Apr 8 2020, 6:51 AM

So you only do the lookup in the global scope? What about namespace std?

Do you also plan to support class methods by looking up the class first and then looking up the method in the class?

I suspect your change made compiler errors a bit nicer as well, so you don't get one giant "Well, this huuuuuge single argument doesn't match any of the assignment operators".

The reason why I added addToFunctionSummaryMap calls is because we have to do a lookup and based on the lookup result we either map the summary or not. (I did not have any problems with the compiler diagnostics regarding the initializer list.)

We don't have any function names that have multiple summaries just yet, correct?

No, we already have a few: e.g. read, write. The reason is that we may not know what is the real type of ssize_t in different platforms, so rather we add int, long and long long return type variants. (An alternative solution could be to support lookup for types as well, so we'd lookup ssize_t in this case.)

Also, this change is NFC, right? Could you make a tag about that to the revision title in the future?

Well, there are functional changes. We exercise the lookup mechanism that we had not done before. We do not add a summary to the map if we cannot lookup the matching prototype. This could lead to different behavior in some cases, hard to find one, but at least in CTU if the ASTImporter assembled an AST where the Decls are not added properly to their DeclContext, then lookup would not find a function.

In D77641#1969412, @NoQ wrote:

So you only do the lookup in the global scope? What about namespace std?

Do you also plan to support class methods by looking up the class first and then looking up the method in the class?

Yes, I had been planning with those. When it comes to the point where we'd like to add summaries for C++ functions (in namespaces or member functions) then we can add a new overloaded operator() to AddToFunctionSummaryMap. In this new function we could handle a fully qualified name (e.g. std::map::insert) by doing the lookup in each found DeclContext starting from the TranslationUnitDecl. (Naturally, we'd not support ADL or using declaration kind of lookup modifications, only fully qualified names would be allowed.) Note that we could give a summary only to those functions that can be found by qualified [Obj]C/C++ lookup. So, e.g. functions in unnamed namespaces or in-class defined friend functions are out of this game.

@NoQ Do these changes look okay to land? Thanks :)

I think you can go ahead and commit. You seem to have a firm grasp on this project, I believe your experience with ASTImporter has more then prepared you for digging functions out of the std namespace, or whatever else that might come up :^)

This revision was automatically updated to reflect the committed changes.

I think you can go ahead and commit. You seem to have a firm grasp on this project, I believe your experience with ASTImporter has more then prepared you for digging functions out of the std namespace, or whatever else that might come up :^)

Alright, thanks, just did the commit. Let me know guys if you find anything else and I'll address the concerns. Also, if there is any regression I'll do the revert, just leave a note here.