NoQ created this revision.
NoQ added reviewers: dcoughlin, george.karpenkov.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, Szelethus, 
mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, kristof.beyls, 
xazax.hun, javed.absar.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D56823

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


Index: test/Analysis/properties.m
===================================================================
--- test/Analysis/properties.m
+++ test/Analysis/properties.m
@@ -1005,3 +1005,38 @@
 
 #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
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -807,6 +807,11 @@
 
   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: test/Analysis/properties.m
===================================================================
--- test/Analysis/properties.m
+++ test/Analysis/properties.m
@@ -1005,3 +1005,38 @@
 
 #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
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -807,6 +807,11 @@
 
   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();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to