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