]> granicus.if.org Git - clang/commitdiff
[analyzer] Do not try to body-farm Objective-C properties with custom accessors.
authorArtem Dergachev <artem.dergachev@gmail.com>
Fri, 18 Jan 2019 22:52:13 +0000 (22:52 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Fri, 18 Jan 2019 22:52:13 +0000 (22:52 +0000)
If a property is defined with a custom getter, we should not behave as if
the getter simply returns an instance variable. We don't support setters,
so they aren't affected.

On top of being the right thing to do, this also fixes a crash on
the newly added test - in which a property and its getter are defined
in two separate categories.

rdar://problem/47051544

Differential Revision: https://reviews.llvm.org/D56823

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351609 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/BodyFarm.cpp
test/Analysis/properties.m

index 35f046406763dd7f7c3d921a52eee299e68396d2..2a682a8ba42e2c070233610e2399d13d4b02e3e3 100644 (file)
@@ -807,6 +807,11 @@ Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
 
   D = D->getCanonicalDecl();
 
+  // We should not try to synthesize explicitly redefined accessors.
+  // We do not know for sure how they behave.
+  if (!D->isImplicit())
+    return nullptr;
+
   Optional<Stmt *> &Val = Bodies[D];
   if (Val.hasValue())
     return Val.getValue();
index 461639f4c2bf09c45fc8a1fc701a6f4ce8bdb80b..17b156035a3406fcc0123676602c840424caa1a9 100644 (file)
@@ -1005,3 +1005,38 @@ void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll() {
 
 #endif // non-ARC
 
+@interface ExplicitAccessorInCategory : NSObject
+@property(readonly) int normal;
+- (int)normal;
+@property(readonly) int no_custom_accessor;
+@end
+
+@interface ExplicitAccessorInCategory ()
+@property(readonly) int in_category;
+
+@property(readonly) int still_no_custom_accessor;
+// This is an ordinary method, not a getter.
+- (int)still_no_custom_accessor;
+@end
+
+@interface ExplicitAccessorInCategory ()
+- (int)in_category;
+
+// This is an ordinary method, not a getter.
+- (int)no_custom_accessor;
+@end
+
+@implementation ExplicitAccessorInCategory
+- (void)foo {
+       // Make sure we don't farm bodies for explicit accessors: in particular,
+       // we're not sure that the accessor always returns the same value.
+       clang_analyzer_eval(self.normal == self.normal); // expected-warning{{UNKNOWN}}
+       // Also this used to crash.
+       clang_analyzer_eval(self.in_category == self.in_category); // expected-warning{{UNKNOWN}}
+
+       // When there is no explicit accessor defined (even if it looks like there is),
+       // farm the getter body and see if it does actually always yield the same value.
+       clang_analyzer_eval(self.no_custom_accessor == self.no_custom_accessor); // expected-warning{{TRUE}}
+       clang_analyzer_eval(self.still_no_custom_accessor == self.still_no_custom_accessor); // expected-warning{{TRUE}}
+}
+@end