// RUN: %clang_analyze_cc1 -w -fblocks -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 @protocol SomeProtocol // Don't warn on protocol properties because it is possible to // conform to them correctly; it is only synthesized setters that // that are definitely incorrect. @property (copy) NSMutableString *myProp; // no-crash // no-warning @end |