120 lines
3.5 KiB
Objective-C
120 lines
3.5 KiB
Objective-C
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s
|
|
|
|
typedef signed char BOOL;
|
|
typedef unsigned int NSUInteger;
|
|
typedef struct _NSZone NSZone;
|
|
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
|
|
@protocol NSObject - (BOOL)isEqual:(id)object; @end
|
|
@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
|
|
@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
|
|
@interface NSObject <NSObject> {} @end
|
|
extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
|
|
@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; @end
|
|
typedef float CGFloat;
|
|
typedef struct _NSPoint {} NSRange;
|
|
@interface NSValue (NSValueRangeExtensions) + (NSValue *)valueWithRange:(NSRange)range;
|
|
- (BOOL)containsObject:(id)anObject;
|
|
@end
|
|
@class NSURLAuthenticationChallenge;
|
|
@interface NSResponder : NSObject <NSCoding> {} @end
|
|
@class NSArray, NSDictionary, NSString;
|
|
@interface NSObject (NSKeyValueBindingCreation)
|
|
+ (void)exposeBinding:(NSString *)binding;
|
|
- (NSArray *)exposedBindings;
|
|
@end
|
|
extern NSString *NSAlignmentBinding;
|
|
|
|
// This test case was reported as a false positive due to a bug in the
|
|
// LiveVariables <-> deadcode.DeadStores interplay. We should not flag a warning
|
|
// here. The test case was reported in:
|
|
// http://lists.llvm.org/pipermail/cfe-dev/2008-July/002157.html
|
|
void DeadStoreTest(NSObject *anObject) {
|
|
NSArray *keys;
|
|
if ((keys = [anObject exposedBindings]) && // no-warning
|
|
([keys containsObject:@"name"] && [keys containsObject:@"icon"])) {}
|
|
}
|
|
|
|
// This test case was a false positive due to how clang models
|
|
// pointer types and ObjC object pointer types differently. Here
|
|
// we don't warn about a dead store because 'nil' is assigned to
|
|
// an object pointer for the sake of defensive programming.
|
|
void rdar_7631278(NSObject *x) {
|
|
x = ((void*)0);
|
|
}
|
|
|
|
// This test case issuing a bogus warning for the declaration of 'isExec'
|
|
// because the compound statement for the @synchronized was being visited
|
|
// twice by the LiveVariables analysis.
|
|
BOOL baz_rdar8527823();
|
|
void foo_rdar8527823();
|
|
@interface RDar8527823
|
|
- (void) bar_rbar8527823;
|
|
@end
|
|
@implementation RDar8527823
|
|
- (void) bar_rbar8527823
|
|
{
|
|
@synchronized(self) {
|
|
BOOL isExec = baz_rdar8527823(); // no-warning
|
|
if (isExec) foo_rdar8527823();
|
|
}
|
|
}
|
|
@end
|
|
|
|
// Don't flag dead stores to assignments to self within a nested assignment.
|
|
@interface Rdar7947686
|
|
- (id) init;
|
|
@end
|
|
|
|
@interface Rdar7947686_B : Rdar7947686
|
|
- (id) init;
|
|
@end
|
|
|
|
@implementation Rdar7947686_B
|
|
- (id) init {
|
|
id x = (self = [super init]);
|
|
// expected-warning@-1 {{Although the value stored to 'self'}}
|
|
return x;
|
|
}
|
|
@end
|
|
|
|
// Don't flag dead stores when a variable is captured in a block used
|
|
// by a property access.
|
|
@interface RDar10591355
|
|
@property (assign) int x;
|
|
@end
|
|
|
|
RDar10591355 *rdar10591355_aux();
|
|
|
|
void rdar10591355() {
|
|
RDar10591355 *p = rdar10591355_aux();
|
|
^{ (void) p.x; }();
|
|
}
|
|
|
|
@interface Radar11059352_1 {
|
|
@private
|
|
int *_pathString;
|
|
}
|
|
@property int *pathString;
|
|
@end
|
|
@interface Radar11059352 {
|
|
@private
|
|
Radar11059352_1 *_Path;
|
|
}
|
|
@end
|
|
@implementation Radar11059352
|
|
|
|
- (int*)usePath {
|
|
Radar11059352_1 *xxxxx = _Path; // no warning
|
|
int *wp = xxxxx.pathString;
|
|
return wp;
|
|
}
|
|
@end
|
|
|
|
id test_objc_precise_lifetime_foo();
|
|
void test_objc_precise_lifetime() {
|
|
__attribute__((objc_precise_lifetime)) id dead = test_objc_precise_lifetime_foo(); // no-warning
|
|
dead = 0;
|
|
dead = test_objc_precise_lifetime_foo(); // no-warning
|
|
dead = 0;
|
|
}
|