This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Fix ObjC Dealloc Checker to operate only on classes with retained properties
ClosedPublic

Authored by dcoughlin on Aug 22 2014, 4:08 AM.

Details

Summary

Previously the ObjC Dealloc Checker only checked classes with ivars, not retained properties, which caused three bugs:

  1. False positive warnings about a missing -dealloc method in classes with only ivars. (rdar://problem/6074390&6244594)
  2. Missing warnings about a missing -dealloc method on classes with only properties. (rdar://problem/13089741)
  3. Missing warnings about an over-released or under-released ivar associated with a retained property in classes with only properties. (rdar://problem/8154447)

The fix is to check only classes with at least one retained, synthesized, writable property.

This also exposed a bug when reporting an over-released or under-released property that did not contain a synthesize statement. The checker tried to associate the warning with an @synthesize statement that did not exist, which caused an assertion failure in debug builds. The fix is to fall back to the @property statement in this case.

Diff Detail

Repository
rL LLVM

Event Timeline

ddkilzer updated this revision to Diff 12837.Aug 22 2014, 4:08 AM
ddkilzer retitled this revision from to [analysis] Add test for missing -dealloc method in classes with an ivar.
ddkilzer updated this object.
ddkilzer edited the test plan for this revision. (Show Details)
ddkilzer added a reviewer: jordan_rose.
ddkilzer added a subscriber: Unknown Object (MLST).

Note that I removed whitespace from the end of line 29 (line 41 on the right), but Phabricator is not showing that as a changed line: https://secure.phabricator.com/T5948

I would have added a similar test for a class with a @property, but I need to fix a couple of bugs before posting that patch.

Currently the checker doesn't warn at all for classes with no -dealloc method and a (retain) @property, and after fixing that issue, leaving out the @synthesize statement causes the checker to crash (apparently because it's trying to attach the warning to the @synthesize statement when it doesn't exist).

jordan_rose edited edge metadata.Aug 22 2014, 9:00 AM

Yup, this checker predates property auto-synthesis!

I'm actually not sure we want to have this particular check; from just the ivar, you can't tell its ownership convention. The properties are very valuable though.

Also, while you're here, make sure we don't do any of this under ARC!

ddkilzer added a comment.EditedAug 22 2014, 10:30 AM

Yup, this checker predates property auto-synthesis!

I'm actually not sure we want to have this particular check; from just the ivar, you can't tell its ownership convention. The properties are very valuable though.

This false positive is filed as rdar://problem/6074390.

Also, while you're here, make sure we don't do any of this under ARC!

Will do. I guess I need to change the test file to include multiple "RUN" commands like this one:

test/SemaObjC/warn-missing-super.m
ddkilzer retitled this revision from [analysis] Add test for missing -dealloc method in classes with an ivar to [analyzer] Add test for missing -dealloc method in classes with an ivar.Aug 22 2014, 12:17 PM
ddkilzer edited edge metadata.
ddkilzer updated this revision to Diff 12883.Aug 23 2014, 12:26 PM

Address Jordan's concern about the false-positive warning for the missing -dealloc method (rdar://problem/6074390) and fix bugs for missing warnings with retained properties.

ddkilzer retitled this revision from [analyzer] Add test for missing -dealloc method in classes with an ivar to [analyzer] Fix ObjC Dealloc Checker to operate only on classes with retained properties .Aug 23 2014, 12:29 PM
ddkilzer updated this object.
ddkilzer edited the test plan for this revision. (Show Details)
ddkilzer added a reviewer: krememek.
ddkilzer updated this object.Aug 29 2014, 10:15 AM
zaks.anna added inline comments.
lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
115 ↗(On Diff #12883)

We try to keep the codebase clear of radar (and PR) numbers. These are very welcome in the commit messages and test cases.

206 ↗(On Diff #12883)

Would it be possible to move the checking of the setter (to be not 'assign') into the body of isSynthesizedWritablePointerProperty() ?

test/Analysis/DeallocMissingRelease.m
142 ↗(On Diff #12883)

All of the run lines are usually placed in the front of the test file.

test/Analysis/MissingDealloc.m
139 ↗(On Diff #12883)

Run commands need to go into the beginning of the file.

test/Analysis/PR2978.m
36 ↗(On Diff #12883)

We prefer to keep the warning messages as short as possible. (One reason is that the IDE real estate is at a premium.) So here, I would drop "Objective-C class".

Thanks for the comments, Anna! I will post a new patch soon.

lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
108 ↗(On Diff #12883)

None of these checks is useful for ARC (-fobjc-arc), so I need to assert this is never called in ARC mode (which Jordan alluded to in a previous comment).

206 ↗(On Diff #12883)

I can, but it makes it harder to share code with the patch in D5042, since I need that bit of information separately.

255–256 ↗(On Diff #12883)

None of these checks is useful for ARC (-fobjc-arc), so I need to return early for ARC mode as well (which Jordan alluded to in a previous comment).

ddkilzer added inline comments.Aug 29 2014, 3:59 PM
test/Analysis/DeallocMissingRelease.m
142 ↗(On Diff #12883)

Just the RUN lines, but not the CHECK* lines? Or both of them together? (Sorry, I was working off a poor example when I moved them to the end of the file.)

ddkilzer added inline comments.Aug 29 2014, 4:28 PM
test/Analysis/DeallocMissingRelease.m
142 ↗(On Diff #12883)

Ignore me. I found the answer in more recent test files: All the Things™ at the top.

ddkilzer updated this revision to Diff 13121.Aug 30 2014, 1:35 AM
ddkilzer retitled this revision from [analyzer] Fix ObjC Dealloc Checker to operate only on classes with retained properties to [analyzer] Fix ObjC Dealloc Checker to operate only on classes with retained properties.
ddkilzer edited the test plan for this revision. (Show Details)

Properly address Jordan's comment about this checker not running with ARC, and address all but one of Anna's comments.

Note that I can't move the check for the setter not being 'assign' into isSynthesizedWritablePointerProperty() since I need that value separately (not logically and-ed with the other checks) in both places where isSynthesizedWritablePointerPropert() is called.

ddkilzer updated this object.Sep 4 2014, 5:55 AM
ddkilzer updated this object.Sep 4 2014, 6:12 AM

More comments. Thanks for working on this!

lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
91 ↗(On Diff #13121)

This should use isObjCRetainableType, to handle blocks as well.

94–96 ↗(On Diff #13121)

I think you can just assert this. Sema should already reject @synthesize without @property, and it will certainly never auto-synthesize a property that doesn't exist.

98 ↗(On Diff #13121)

I don't think this matters. As soon as the property is synthesized, it needs to be released, right?

123–125 ↗(On Diff #13121)

...or Weak.

203 ↗(On Diff #13121)

'Weak' also doesn't require a release.

test/Analysis/DeallocMissingRelease.m
2–5 ↗(On Diff #13121)

Please move these checks inline. That way they're associated with what they're checking, and you can use [[@LINE]] (or [[@LINE+1]] or [[@LINE-1]] to provide a relative line number.

16–25 ↗(On Diff #13121)

This is not helpful; the analyzer doesn't even get run when there are AST-level errors. Can you #if out the problematic lines when testing under ARC?

dcoughlin commandeered this revision.Jan 7 2016, 5:51 PM
dcoughlin edited reviewers, added: ddkilzer; removed: dcoughlin.

I am commandeering this revision!

dcoughlin updated this revision to Diff 45756.Jan 22 2016, 3:05 PM
dcoughlin marked 6 inline comments as done.

I've updated ddkilzer's patch to address Jordan's last round of comments.

Specifically, I have:

  • Changed the patch to use isObjCRetainableType() to additional warn about properties of block type(and added a test).
  • Added an assertion that a synthesized property implementation has a property declaration.
  • Changed the patch to warn on readonly synthesized properties (and added tests).
  • Changed the patch to not warn on weak properties.
  • Removed tests for GC environments.
  • Moved CHECK lines to be in-line with test code.
This revision was automatically updated to reflect the committed changes.