diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
| commit | 73490b890977362d28dd6326843a1ecae413921d (patch) | |
| tree | 3fdd91eae574e32453a4baf462961c742df2691a /test/Analysis | |
| parent | a5f348eb914e67b51914117fac117c18c1f8d650 (diff) | |
Notes
Diffstat (limited to 'test/Analysis')
| -rw-r--r-- | test/Analysis/misc-ps-region-store.m | 69 | ||||
| -rw-r--r-- | test/Analysis/misc-ps.m | 34 | ||||
| -rw-r--r-- | test/Analysis/refcnt_naming.m | 4 | ||||
| -rw-r--r-- | test/Analysis/retain-release-region-store.m | 85 | ||||
| -rw-r--r-- | test/Analysis/retain-release.m | 38 |
5 files changed, 214 insertions, 16 deletions
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index e849042b3d3d..b6fff102a701 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -141,9 +141,11 @@ again: } } +//===----------------------------------------------------------------------===// // Reduced test case from <rdar://problem/7114618>. // Basically a null check is performed on the field value, which is then // assigned to a variable and then checked again. +//===----------------------------------------------------------------------===// struct s_7114618 { int *p; }; void test_rdar_7114618(struct s_7114618 *s) { if (s->p) { @@ -168,9 +170,11 @@ void f() { } } +//===----------------------------------------------------------------------===// // <rdar://problem/7185607> // Bit-fields of a struct should be invalidated when blasting the entire // struct with an integer constant. +//===----------------------------------------------------------------------===// struct test_7185607 { int x : 10; int y : 22; @@ -181,9 +185,11 @@ int rdar_test_7185607() { return s.x; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7242006> [RegionStore] compound literal assignment with // floats not honored // This test case is mirrored in misc-ps.m, but this case is a negative. +//===----------------------------------------------------------------------===// typedef float CGFloat; typedef struct _NSSize { CGFloat width; @@ -195,9 +201,11 @@ CGFloat rdar7242006_negative(CGFloat x) { return y.width; // expected-warning{{garbage}} } +//===----------------------------------------------------------------------===// // <rdar://problem/7249340> - Allow binding of values to symbolic regions. // This test case shows how RegionStore tracks the value bound to 'x' // after the assignment. +//===----------------------------------------------------------------------===// typedef int* ptr_rdar_7249340; void rdar_7249340(ptr_rdar_7249340 x) { *x = 1; @@ -207,11 +215,13 @@ void rdar_7249340(ptr_rdar_7249340 x) { *p = 0xDEADBEEF; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7249327> - This test case tests both value tracking of // array values and that we handle symbolic values that are casted // between different integer types. Note the assignment 'n = *a++'; here // 'n' is and 'int' and '*a' is 'unsigned'. Previously we got a false positive // at 'x += *b++' (undefined value) because we got a false path. +//===----------------------------------------------------------------------===// int rdar_7249327_aux(void); void rdar_7249327(unsigned int A[2*32]) { @@ -237,8 +247,10 @@ void rdar_7249327(unsigned int A[2*32]) { x += *b++; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/6914474> - Check that 'x' is invalidated because its // address is passed in as a value to a struct. +//===----------------------------------------------------------------------===// struct doodad_6914474 { int *v; }; extern void prod_6914474(struct doodad_6914474 *d); int rdar_6914474(void) { @@ -278,8 +290,11 @@ int test_handle_array_wrapper() { return p->z; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7261075> [RegionStore] crash when // handling load: '*((unsigned int *)"????")' +//===----------------------------------------------------------------------===// + int rdar_7261075(void) { unsigned int var = 0; if (var == *((unsigned int *)"????")) @@ -287,8 +302,11 @@ int rdar_7261075(void) { return 0; } +//===----------------------------------------------------------------------===// // <rdar://problem/7275774> false path due to limited pointer // arithmetic constraints +//===----------------------------------------------------------------------===// + void rdar_7275774(void *data, unsigned n) { if (!(data || n == 0)) return; @@ -303,3 +321,54 @@ void rdar_7275774(void *data, unsigned n) { } } +//===----------------------------------------------------------------------===// +// <rdar://problem/7312221> +// +// Test that Objective-C instance variables aren't prematurely pruned +// from the analysis state. +//===----------------------------------------------------------------------===// + +struct rdar_7312221_value { int x; }; + +@interface RDar7312221 +{ + struct rdar_7312221_value *y; +} +- (void) doSomething_7312221; +@end + +extern struct rdar_7312221_value *rdar_7312221_helper(); +extern int rdar_7312221_helper_2(id o); +extern void rdar_7312221_helper_3(int z); + +@implementation RDar7312221 +- (void) doSomething_7312221 { + if (y == 0) { + y = rdar_7312221_helper(); + if (y != 0) { + y->x = rdar_7312221_helper_2(self); + // The following use of 'y->x' previously triggered a null dereference, as the value of 'y' + // before 'y = rdar_7312221_helper()' would be used. + rdar_7312221_helper_3(y->x); // no-warning + } + } +} +@end + +struct rdar_7312221_container { + struct rdar_7312221_value *y; +}; + +extern int rdar_7312221_helper_4(struct rdar_7312221_container *s); + +// This test case essentially matches the one in [RDar7312221 doSomething_7312221]. +void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) { + if (Self->y == 0) { + Self->y = rdar_7312221_helper(); + if (Self->y != 0) { + Self->y->x = rdar_7312221_helper_4(Self); + rdar_7312221_helper_3(Self->y->x); // no-warning + } + } +} + diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 10e5823c206c..fcc13a39a461 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -681,14 +681,40 @@ void *rdar7152418_bar(); return 1; } +//===----------------------------------------------------------------------===// // Test constant-folding of symbolic values, automatically handling type -// conversions of the symbol as necessary. Previously this would crash -// once we started eagerly evaluating symbols whose values were constrained -// to a single value. -void test_constant_symbol(signed char x) { +// conversions of the symbol as necessary. +//===----------------------------------------------------------------------===// + + +// Previously this would crash once we started eagerly evaluating symbols whose +// values were constrained to a single value. +void test_symbol_fold_1(signed char x) { while (1) { if (x == ((signed char) 0)) {} } } +// This previously caused a crash because it triggered an assertion in APSInt. +void test_symbol_fold_2(unsigned int * p, unsigned int n, + const unsigned int * grumpkin, unsigned int dn) { + unsigned int i; + unsigned int tempsub[8]; + unsigned int *solgrumpkin = tempsub + n; + for (i = 0; i < n; i++) + solgrumpkin[i] = (i < dn) ? ~grumpkin[i] : 0xFFFFFFFF; + for (i <<= 5; i < (n << 5); i++) {} +} + +// This previously caused a crash because it triggered an assertion in APSInt. +// 'x' would evaluate to a 8-bit constant (because of the return value of +// test_symbol_fold_3_aux()) which would not get properly promoted to an +// integer. +char test_symbol_fold_3_aux(void); +unsigned test_symbol_fold_3(void) { + unsigned x = test_symbol_fold_3_aux(); + if (x == 54) + return (x << 8) | 0x5; + return 0; +} diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m index bea404799ba3..2ce00b2a8cca 100644 --- a/test/Analysis/refcnt_naming.m +++ b/test/Analysis/refcnt_naming.m @@ -15,7 +15,7 @@ typedef signed char BOOL; -(NSObject*)photoCopy; // read as "photo Copy" -(NSObject*)__blebPRCopy; // read as "bleb PRCopy" -(NSObject*)__blebPRcopy; // read as "bleb P Rcopy" --(NSObject*)new_theprefixdoesnotcount; // read as "theprefixdoesnotcount" +-(NSObject*)new_theprefixdoescount; // read as "new theprefixdoescount" -(NSObject*)newestAwesomeStuff; // read as "newest awesome stuff" @end @@ -49,7 +49,7 @@ void testNames(NamingTest* x) { [x photoCopy]; // expected-warning{{leak}} [x __blebPRCopy]; // expected-warning{{leak}} [x __blebPRcopy]; // no-warning - [x new_theprefixdoesnotcount]; // no-warning + [x new_theprefixdoescount]; // expected-warning{{leak}} [x newestAwesomeStuff]; // no-warning } diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m index 7a696833f92d..eacac49c8127 100644 --- a/test/Analysis/retain-release-region-store.m +++ b/test/Analysis/retain-release-region-store.m @@ -1,5 +1,4 @@ // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s -// XFAIL //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from @@ -43,14 +42,19 @@ typedef mach_port_name_t mach_port_t; typedef signed char BOOL; typedef struct _NSZone NSZone; @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject - (BOOL)isEqual:(id)object; +@protocol NSObject +- (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end @interface NSObject <NSObject> { -} -@end typedef float CGFloat; +@end +@interface NSObject <NSObject> {} ++ (id)allocWithZone:(NSZone *)zone; ++ (id)alloc; +- (void)dealloc; +@end +typedef float CGFloat; typedef double NSTimeInterval; @interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; @end enum { @@ -74,6 +78,13 @@ kDAReturnSuccess = 0, kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff typedef mach_error_t DAReturn; typedef const struct __DADissenter * DADissenterRef; extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); +@interface NSNumber : NSObject +- (id)initWithInt:(int)value; +@end +typedef unsigned long NSUInteger; +@interface NSArray : NSObject +-(id) initWithObjects:(const id *)objects count:(NSUInteger) cnt; +@end //===----------------------------------------------------------------------===// // Test cases. @@ -116,15 +127,14 @@ CFAbsoluteTime f4() { } @end -//===----------------------------------------------------------------------===// -// <rdar://problem/7257223> - False positive due to not invalidating the -// reference count of a tracked region that was itself invalidated. -//===----------------------------------------------------------------------===// +//===------------------------------------------------------------------------------------------===// +// <rdar://problem/7257223> (also <rdar://problem/7283470>) - False positive due to not invalidating +// the reference count of a tracked region that was itself invalidated. +//===------------------------------------------------------------------------------------------===// typedef struct __rdar_7257223 { CFDateRef x; } RDar7257223; void rdar_7257223_aux(RDar7257223 *p); -// THIS CASE CURRENTLY FAILS. CFDateRef rdar7257223_Create(void) { RDar7257223 s; CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); @@ -140,3 +150,58 @@ CFDateRef rdar7257223_Create_2(void) { return s.x; } +void rdar7283470(void) { + NSNumber *numbers[] = { + [[NSNumber alloc] initWithInt:1], // no-warning + [[NSNumber alloc] initWithInt:2], // no-warning + [[NSNumber alloc] initWithInt:3], // no-warning + [[NSNumber alloc] initWithInt:4], // no-warning + [[NSNumber alloc] initWithInt:5] // no-warning + }; + + for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) + [numbers[i] release]; +} + +void rdar7283470_positive(void) { + NSNumber *numbers[] = { + [[NSNumber alloc] initWithInt:1], // expected-warning{{leak}} + [[NSNumber alloc] initWithInt:2], // expected-warning{{leak}} + [[NSNumber alloc] initWithInt:3], // expected-warning{{leak}} + [[NSNumber alloc] initWithInt:4], // expected-warning{{leak}} + [[NSNumber alloc] initWithInt:5] // expected-warning{{leak}} + }; +} + +void rdar7283470_2(void) { + NSNumber *numbers[] = { + [[NSNumber alloc] initWithInt:1], // no-warning + [[NSNumber alloc] initWithInt:2], // no-warning + [[NSNumber alloc] initWithInt:3], // no-warning + [[NSNumber alloc] initWithInt:4], // no-warning + [[NSNumber alloc] initWithInt:5] // no-warning + }; + + NSArray *s_numbers =[[NSArray alloc] initWithObjects:&numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; + + for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) + [numbers[i] release]; + + [s_numbers release]; +} + +void rdar7283470_2_positive(void) { + NSNumber *numbers[] = { + [[NSNumber alloc] initWithInt:1], // no-warning + [[NSNumber alloc] initWithInt:2], // no-warning + [[NSNumber alloc] initWithInt:3], // no-warning + [[NSNumber alloc] initWithInt:4], // no-warning + [[NSNumber alloc] initWithInt:5] // no-warning + }; + + NSArray *s_numbers =[[NSArray alloc] initWithObjects: &numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; // expected-warning{{leak}} + + for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) + [numbers[i] release]; +} + diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 7076bb294254..e620037b2c14 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1098,6 +1098,44 @@ CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, } //===----------------------------------------------------------------------===// +// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to +// start before '_' when determining Cocoa fundamental rule +// +// Previously the retain/release checker just skipped prefixes before the +// first '_' entirely. Now the checker honors the prefix if it results in a +// recognizable naming convention (e.g., 'new', 'init'). +//===----------------------------------------------------------------------===// + +@interface RDar7265711 {} +- (id) new_stuff; +@end + +void rdar7265711_a(RDar7265711 *x) { + id y = [x new_stuff]; // expected-warning{{leak}} +} + +void rdar7265711_b(RDar7265711 *x) { + id y = [x new_stuff]; // no-warning + [y release]; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a +// retained reference +//===----------------------------------------------------------------------===// + +@interface NSCursor : NSObject ++ (NSCursor *)dragCopyCursor; +@end + +void rdar7306898(void) { + // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence + // implying a 'copy' of something. + NSCursor *c = [NSCursor dragCopyCursor]; // no-warning + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===// |
