This is an archive of the discontinued LLVM Phabricator instance.

[wip] [analyzer] support use-after-free checking with parameter annotation
Needs ReviewPublic

Authored by chrisdangelo on Nov 9 2021, 5:17 PM.

Details

Reviewers
NoQ
aaron.ballman
Summary

This change adds a more ergonomic alternative to the function-based attribute ownership_takes, ownership_holds, and ownership_returns.

This change is a work in progress. This change is planned for posting privately for initial review with Artem Dergachev. After which, this is planned for sharing with Aaron Ballman.

Diff Detail

Unit TestsFailed

Event Timeline

chrisdangelo requested review of this revision.Nov 9 2021, 5:17 PM
chrisdangelo created this revision.
chrisdangelo created this object with visibility "chrisdangelo (Chris D'Angelo)".
Herald added a project: Restricted Project. · View Herald TranscriptNov 9 2021, 5:17 PM
chrisdangelo retitled this revision from [analyzer] support use-after-free checking with parameter annotation to [wip] [analyzer] support use-after-free checking with parameter annotation.
chrisdangelo changed the visibility from "chrisdangelo (Chris D'Angelo)" to "Public (No Login Required)".Nov 15 2021, 2:16 PM
chrisdangelo added inline comments.Nov 15 2021, 3:10 PM
clang/include/clang/Basic/Attr.td
2263

I've discussed this a bit with Artem in person today. Artem would like to see if the existing "ownership_takes" attribute can be adjusted to include the ability to be used against a parameter. I'm looking into this now.

chrisdangelo updated this revision to Diff 395726.EditedDec 21 2021, 11:36 AM
chrisdangelo edited the summary of this revision. (Show Details)

This change removes the previous ownership_takes_param work. This change augments the existing Ownership attribute so that it is now applicable to function parameters.

Theses changes have been used to run the analyzer on a large C / C++ project. The tests have been run locally and successfully with ninja check-clang-analysis and ninja check-clang.

This diff is functional but is not fully complete. As of this iteration, these are the current tasks unresolved...

  1. This change does not fully validate correct usage in SemaDeclAttr.cpp. More can be done to validate that ownership attributes are not used in ways that are in conflict with one another. This conflict can occur with a combination of ownership attributes applied to the function declaration simultaneously with parameter annotations.
  1. We are interested in deprecating the use of function based ownership attributes in favor of using function parameter annotations. This change does not currently provide deprecation warnings.
  1. This change does not test semantic analysis of ownership parameters (attr-ownership.c/cpp).
  1. This change does not fully test static analysis of ownership parameters (malloc-annotations.c).

This change includes clang-format edits.

NoQ added a comment.Dec 21 2021, 12:28 PM

I'm really glad it actually works!

We are interested in deprecating the use of function based ownership attributes in favor of using function parameter annotations. This change does not currently provide deprecation warnings.

Do we also need to convert ownership_holds to parameter attribute? I think it doesn't make sense to deprecate until we convert all of them.

This change does not fully test static analysis of ownership parameters (malloc-annotations.c).

I think it makes sense to simply copy that file and replace function attributes with parameter attributes and see if it still passes.

clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
1528

Call.getDecl() is intended to be the ultimate source of truth on this subject.

chrisdangelo added inline comments.Dec 21 2021, 5:31 PM
clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
1528

Thank you. This function definition has been removed and the call-site has changed to...

const Decl *D = Call.getDecl();
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
if (!FD)
  return;

... I plan to push the above changes soon to Differential. The tests pass successfully using ninja check-clang-analysis.

Previously, functionDeclForCall mimicked the existing solution using const FunctionDecl *FD = C.getCalleeDecl(CE);. I'm not sure what that existing solution provided differently from Call.getDecl().

chrisdangelo updated this revision to Diff 395926.EditedDec 22 2021, 1:55 PM

A) "I think it makes sense to simply copy that file and replace function attributes with parameter attributes and see if it still passes." - @NoQ (Tue, Dec 21, 12:28 PM)

Sounds good. This newest change adds malloc-annotations-param.c and malloc-annotations-param.cpp.

This change begins work to use ownership_takes and ownership_holds parameter attributes for the same tests still using function attributes in malloc-annotations.c and malloc-annotations.cpp respectively.

Note that this is just the beginning of the work to test parameter based ownership attributes. There are many misuse scenarios that are currently not supported in these changes, and not tested.

I've explained a bit more below, and plan to explain a bit more on the comment coinciding with the next Differential attachment.

B) "Do we also need to convert ownership_holds to parameter attribute? I think it doesn't make sense to deprecate until we convert all of them." - @NoQ (Tue, Dec 21, 12:28 PM)

ownership_holds is expected to be functioning. However, there are several misuse scenarios that I've not yet accounted for.

Example 1: What happens if the developer uses the function attribute and parameter attribute on the same parameter with different ownership types?

Example 2: What happens if the developer uses multiple parameter attributes of varying owernship types on the same parameter?

Additionally, ownership_returns compile-time or analysis-time validation is not completely or correctly supported today. For example, nothing prevents the developer from attempting to apply ownership_returns to a parameter in a function.

C) These changes have been tested by successfully running ninja check-clang-analysis.