aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/ObjCPropertiesSyntaxChecks.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/ObjCPropertiesSyntaxChecks.m')
-rw-r--r--test/Analysis/ObjCPropertiesSyntaxChecks.m61
1 files changed, 61 insertions, 0 deletions
diff --git a/test/Analysis/ObjCPropertiesSyntaxChecks.m b/test/Analysis/ObjCPropertiesSyntaxChecks.m
new file mode 100644
index 000000000000..5c642c581736
--- /dev/null
+++ b/test/Analysis/ObjCPropertiesSyntaxChecks.m
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=osx.ObjCProperty %s -verify
+
+#include "Inputs/system-header-simulator-objc.h"
+
+@interface I : NSObject {
+ NSMutableString *_mutableExplicitStr;
+ NSMutableString *_trulyMutableStr;
+ NSMutableString *_trulyMutableExplicitStr;
+}
+@property(copy) NSString *str; // no-warning
+@property(copy) NSMutableString *mutableStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property(copy) NSMutableString *mutableExplicitStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property(copy, readonly) NSMutableString *mutableReadonlyStr; // no-warning
+@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInChild; // no-warning
+@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInCategory; // no-warning
+@property(copy) NSMutableString *trulyMutableStr; // no-warning
+@property(copy) NSMutableString *trulyMutableExplicitStr; // no-warning
+@property(copy) NSMutableString *trulyMutableStrWithSynthesizedStorage; // no-warning
+@end
+
+@interface I () {}
+@property(copy) NSMutableString *mutableStrInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@end
+
+@implementation I
+@synthesize mutableExplicitStr = _mutableExplicitStr;
+- (NSMutableString *)trulyMutableStr {
+ return _trulyMutableStr;
+}
+- (void)setTrulyMutableStr: (NSMutableString *) S {
+ _trulyMutableStr = [S mutableCopy];
+}
+@dynamic trulyMutableExplicitStr;
+- (NSMutableString *)trulyMutableExplicitStr {
+ return _trulyMutableExplicitStr;
+}
+- (void)setTrulyMutableExplicitStr: (NSMutableString *) S {
+ _trulyMutableExplicitStr = [S mutableCopy];
+}
+@synthesize trulyMutableStrWithSynthesizedStorage;
+- (NSMutableString *)trulyMutableStrWithSynthesizedStorage {
+ return trulyMutableStrWithSynthesizedStorage;
+}
+- (void)setTrulyMutableStrWithSynthesizedStorage: (NSMutableString *) S {
+ trulyMutableStrWithSynthesizedStorage = [S mutableCopy];
+}
+@end
+
+@interface J : I {}
+@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInChild; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@end
+
+@implementation J
+@end
+
+// If we do not see the implementation then we do not want to warn,
+// because we may miss a user-defined setter that works correctly.
+@interface IWithoutImpl : NSObject {}
+@property(copy) NSMutableString *mutableStr; // no-warning
+@end