This is an archive of the discontinued LLVM Phabricator instance.

[Analyzer] Allow creation of stack frame for functions without definition
ClosedPublic

Authored by baloghadamsoftware on May 20 2020, 3:28 AM.

Details

Summary

Retrieving the parameter location of functions was disabled because it may causes crashes due to the fact that functions may have multiple declarations and without definition it is difficult to ensure that always the same declration is used. Now parameters are stored in ParamRegions which are independent of the declaration of the function, therefore the same parameters always have the same regions, independently of the function declaration used actually. This allows us to remove the limitation described above.

Diff Detail

Event Timeline

baloghadamsoftware marked 2 inline comments as done.May 20 2020, 3:34 AM

I tested this on several open-source projects: BitCoin, CURL, OpenSLL, PostGreS, TMux, Xerces and even on LLVM itself with most of the projects enabled. No new crash and no change in findings. So it seems to be stable.

clang/lib/StaticAnalyzer/Core/CallEvent.cpp
179

We introduced ParamRegions to overcome this, but please provide me the tests that crash when deleting these lines without ParamRegions you mentioned D49443#1193290.

clang/test/Analysis/temporaries.cpp
893

I wonder whether clang_analyzer_checkInlined() works correctly with this patch: it seems it only checks for stack frame which now any function with definition can have.

Retrieving the parameter location of functions was disabled because it may causes crashes due to the fact that functions may have multiple declarations and without definition it is difficult to ensure that always the same declration is used. Now parameters are stored in ParamRegions which are independent of the declaration of the function, therefore the same parameters always have the same regions, independently of the function declaration used actually. This allows us to remove the limitation described above.

I am not sure if this "summary" for the patch is aligned with its title. I think the title says it all, I'd just skip this summary, it is way too blurry for me.
Because:

it may causes crashes

We still need the test cases for that, and I am not sure if we will ever get one.

without definition it is difficult to ensure that always the same declration is used.

That is not difficult in other parts of the compiler infrastructure (e.g in ASTImporter), this statement is just a vague allusion to one or several hypothetical bugs in the analyzer.

the same parameters always have the same regions, independently of the function declaration used actually.

You mentioned personally to me already, but don't forget to add test cases for that.

clang/test/Analysis/temporaries.cpp
893

So, why not try that in a test with a function that does not have a definition?

Added unittest for checking the sameness for the regions of same params with different redeclarations.

martong added inline comments.May 20 2020, 8:01 AM
clang/unittests/StaticAnalyzer/ParamRegionTest.cpp
22

I am concerned about the redeclaration chain of ParmVarDecls. In the following example:

void foo(int a);
void foo(int a);

we have the prev decl set only for the FunctionDecls and not for the ParmVarDecl (please double check).
So in the test we should go through the redecls() of the FunctionDecl of the ParmVarDecl. And we should get a PVD from each redeclaration by the index.

84

I think a raw string literal with clang-formatted code in it would make the test more valuable.

NoQ accepted this revision.May 22 2020, 4:50 AM

This looks straightforward, thanks!

clang/test/Analysis/explain-svals.cpp
101

Wonderful!

I think "parameter 1" would make a bit more sense. Or, even better, "1st parameter" like in regular warnings.

(this probably needs to be fixed in an older patch)

clang/test/Analysis/temporaries.cpp
893

it seems it only checks for stack frame which now any function with definition can have

Before that, it checks that clang_analyzer_checkInlined() was evaluated during analysis. You can't evaluate this line if you didn't analyze ~C() either as top-level function or through inlining.

clang/unittests/StaticAnalyzer/ParamRegionTest.cpp
84

I also think it's going to be valuable to test what's going to happen if the forward-declaration is after the definition; that's where we were previously confused.

This revision is now accepted and ready to land.May 22 2020, 4:50 AM

SVal explanation changed to Xth parameter format. Unit test changed: there is redeclaration after the definition now, all test code in raw string.

baloghadamsoftware marked 3 inline comments as done.May 25 2020, 9:21 AM
This revision was automatically updated to reflect the committed changes.

Unfortunately, after this change there are several variables only used in asserts, which creates build failures when assertions are disabled.

I will be submitting https://reviews.llvm.org/D81522 shortly to fix.

Unfortunately, after this change there are several variables only used in asserts, which creates build failures when assertions are disabled.

I will be submitting https://reviews.llvm.org/D81522 shortly to fix.

What is the point of building unit tests with assertions disabled? To me this looks like a CMake configuration problem. Unit tests should always be built with assertions enabled since they are based on assertions. They are just tests, they do not decrease the performance of the production code.