diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Analysis/BodyFarm.cpp | 5 | ||||
-rw-r--r-- | clang/test/Analysis/properties.m | 35 |
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 |