summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/BodyFarm.cpp5
-rw-r--r--clang/test/Analysis/properties.m35
2 files changed, 40 insertions, 0 deletions
diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp
index 35f04640676..2a682a8ba42 100644
--- a/clang/lib/Analysis/BodyFarm.cpp
+++ b/clang/lib/Analysis/BodyFarm.cpp
@@ -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();
diff --git a/clang/test/Analysis/properties.m b/clang/test/Analysis/properties.m
index 461639f4c2b..17b156035a3 100644
--- a/clang/test/Analysis/properties.m
+++ b/clang/test/Analysis/properties.m
@@ -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
OpenPOWER on IntegriCloud