forked from OSchip/llvm-project
69 lines
3.1 KiB
Objective-C
69 lines
3.1 KiB
Objective-C
// 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
|