1*184c6242SDominic Chen// RUN: %clang_analyze_cc1 -w -fblocks -analyzer-checker=osx.ObjCProperty %s -verify
2e69d2e47SArtem Dergachev
3e69d2e47SArtem Dergachev#include "Inputs/system-header-simulator-objc.h"
4e69d2e47SArtem Dergachev
5e69d2e47SArtem Dergachev@interface I : NSObject {
6e69d2e47SArtem Dergachev  NSMutableString *_mutableExplicitStr;
7e69d2e47SArtem Dergachev  NSMutableString *_trulyMutableStr;
8e69d2e47SArtem Dergachev  NSMutableString *_trulyMutableExplicitStr;
9e69d2e47SArtem Dergachev}
10e69d2e47SArtem Dergachev@property(copy) NSString *str; // no-warning
11e69d2e47SArtem Dergachev@property(copy) NSMutableString *mutableStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
12e69d2e47SArtem Dergachev@property(copy) NSMutableString *mutableExplicitStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
13e69d2e47SArtem Dergachev@property(copy, readonly) NSMutableString *mutableReadonlyStr; // no-warning
14e69d2e47SArtem Dergachev@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInChild; // no-warning
15e69d2e47SArtem Dergachev@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInCategory; // no-warning
16e69d2e47SArtem Dergachev@property(copy) NSMutableString *trulyMutableStr; // no-warning
17e69d2e47SArtem Dergachev@property(copy) NSMutableString *trulyMutableExplicitStr; // no-warning
18e69d2e47SArtem Dergachev@property(copy) NSMutableString *trulyMutableStrWithSynthesizedStorage; // no-warning
19e69d2e47SArtem Dergachev@end
20e69d2e47SArtem Dergachev
21e69d2e47SArtem Dergachev@interface I () {}
22e69d2e47SArtem Dergachev@property(copy) NSMutableString *mutableStrInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
23e69d2e47SArtem Dergachev@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
24e69d2e47SArtem Dergachev@end
25e69d2e47SArtem Dergachev
26e69d2e47SArtem Dergachev@implementation I
27e69d2e47SArtem Dergachev@synthesize mutableExplicitStr = _mutableExplicitStr;
28e69d2e47SArtem Dergachev- (NSMutableString *)trulyMutableStr {
29e69d2e47SArtem Dergachev  return _trulyMutableStr;
30e69d2e47SArtem Dergachev}
31e69d2e47SArtem Dergachev- (void)setTrulyMutableStr: (NSMutableString *) S {
32e69d2e47SArtem Dergachev  _trulyMutableStr = [S mutableCopy];
33e69d2e47SArtem Dergachev}
34e69d2e47SArtem Dergachev@dynamic trulyMutableExplicitStr;
35e69d2e47SArtem Dergachev- (NSMutableString *)trulyMutableExplicitStr {
36e69d2e47SArtem Dergachev  return _trulyMutableExplicitStr;
37e69d2e47SArtem Dergachev}
38e69d2e47SArtem Dergachev- (void)setTrulyMutableExplicitStr: (NSMutableString *) S {
39e69d2e47SArtem Dergachev  _trulyMutableExplicitStr = [S mutableCopy];
40e69d2e47SArtem Dergachev}
41e69d2e47SArtem Dergachev@synthesize trulyMutableStrWithSynthesizedStorage;
42e69d2e47SArtem Dergachev- (NSMutableString *)trulyMutableStrWithSynthesizedStorage {
43e69d2e47SArtem Dergachev  return trulyMutableStrWithSynthesizedStorage;
44e69d2e47SArtem Dergachev}
45e69d2e47SArtem Dergachev- (void)setTrulyMutableStrWithSynthesizedStorage: (NSMutableString *) S {
46e69d2e47SArtem Dergachev  trulyMutableStrWithSynthesizedStorage = [S mutableCopy];
47e69d2e47SArtem Dergachev}
48e69d2e47SArtem Dergachev@end
49e69d2e47SArtem Dergachev
50e69d2e47SArtem Dergachev@interface J : I {}
51e69d2e47SArtem Dergachev@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInChild; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
52e69d2e47SArtem Dergachev@end
53e69d2e47SArtem Dergachev
54e69d2e47SArtem Dergachev@implementation J
55e69d2e47SArtem Dergachev@end
56e69d2e47SArtem Dergachev
57e69d2e47SArtem Dergachev// If we do not see the implementation then we do not want to warn,
58e69d2e47SArtem Dergachev// because we may miss a user-defined setter that works correctly.
59e69d2e47SArtem Dergachev@interface IWithoutImpl : NSObject {}
60e69d2e47SArtem Dergachev@property(copy) NSMutableString *mutableStr; // no-warning
61e69d2e47SArtem Dergachev@end
621bf65c8cSDevin Coughlin
631bf65c8cSDevin Coughlin@protocol SomeProtocol
641bf65c8cSDevin Coughlin// Don't warn on protocol properties because it is possible to
651bf65c8cSDevin Coughlin// conform to them correctly; it is only synthesized setters that
661bf65c8cSDevin Coughlin// that are definitely incorrect.
671bf65c8cSDevin Coughlin@property (copy) NSMutableString *myProp; // no-crash // no-warning
681bf65c8cSDevin Coughlin@end
69