aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
commit73490b890977362d28dd6326843a1ecae413921d (patch)
tree3fdd91eae574e32453a4baf462961c742df2691a /test/Analysis
parenta5f348eb914e67b51914117fac117c18c1f8d650 (diff)
Notes
Diffstat (limited to 'test/Analysis')
-rw-r--r--test/Analysis/misc-ps-region-store.m69
-rw-r--r--test/Analysis/misc-ps.m34
-rw-r--r--test/Analysis/refcnt_naming.m4
-rw-r--r--test/Analysis/retain-release-region-store.m85
-rw-r--r--test/Analysis/retain-release.m38
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.
//===----------------------------------------------------------------------===//