This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Fixing a bug raising false positives of stack block object leaking under ARC
ClosedPublic

Authored by ziqingluo-90 on Aug 2 2022, 12:20 PM.

Details

Summary

When ARC is enabled, (objective-c) block objects are automatically retained and released thus they do not leak.
Without ARC, they still can leak from an expiring stack frame like other stack variables.

This patch simply adds the ARC checking condition onto the changes made in https://reviews.llvm.org/D107078. The checker already checks the same condition for global variables.

Diff Detail

Event Timeline

ziqingluo-90 created this revision.Aug 2 2022, 12:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 12:20 PM
ziqingluo-90 requested review of this revision.Aug 2 2022, 12:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 12:20 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
NoQ added a comment.Aug 8 2022, 12:37 PM

Aha great, I see you've found that there's already an existing solution for this problem! I'm questioning this solution though, maybe a more general solution could have helped us avoid this problem altogether.

clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
304–306

Aha ok, it sounds like we can no longer be sure that the block is on the stack at this point, did I get it right?

In this case I think it's more productive to have the block's memory space be UnknownSpaceRegion from the start, so that it fell through the memory space check, both here and at other call sites of isArcManagedBlock() (so it can be removed), and in any other code that relies on memory spaces (so this mistake is never made again).

ziqingluo-90 added inline comments.Aug 16 2022, 10:39 AM
clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
304–306

" ..., did I get it right?" Yes.

This suggestion makes sense to me. To my understanding, I need to modify the symbolic execution engine to address it. So shall I do it in a new patch?

NoQ added inline comments.Aug 16 2022, 3:30 PM
clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
304–306

There's no need to make a new review, you can update the current review. The test stays the same after all, who knows maybe we'll end up reverting to this solution. It's nice to have all approaches considered and explored behind the same link that ultimately ends up in the commit message.

Addressing @NoQ 's comment. Let the symbolic execution simulator put a block object in an UnknownSpaceRegion from the start if ARC is enabled. Because in such cases whether the block is on stack or in heap depends on the implementation. And, those blocks will be moved to the heap when necessary. So they will never trigger a stack address leak issue.

Removing those ARC checking in StackAddrEscapeChecker since they are no longer needed.

NoQ added a comment.Aug 23 2022, 6:45 PM

Aha perfect, now the entire static analyzer knows how to work with these regions!

I have one tiny remark and I think we can commit.

clang/lib/StaticAnalyzer/Core/MemRegion.cpp
1079–1084

MemRegionManager maintains a reference to the current ASTContext, it's slightly easier to use it directly or through getContext().

There's also a general recommendation to avoid Decl::getASTContext() because it isn't an O(1) operation; instead, it traverses through parent decls all the way up to TranslationUnitDecl which maintains the actual reference to ASTContext. I'm not sure how bad this is, but if it can be easily avoided we probably should.

Aha perfect, now the entire static analyzer knows how to work with these regions!

I have one tiny remark and I think we can commit.

Thank you! I will make the change then directly commit.

NoQ accepted this revision.Aug 24 2022, 6:28 PM

Works for me!

This revision is now accepted and ready to land.Aug 24 2022, 6:28 PM