aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis')
-rw-r--r--test/Analysis/CFDateGC.m8
-rw-r--r--test/Analysis/CheckNSError.m4
-rw-r--r--test/Analysis/NSPanel.m2
-rw-r--r--test/Analysis/NSString.m15
-rw-r--r--test/Analysis/PR2978.m1
-rw-r--r--test/Analysis/PR3991.m1
-rw-r--r--test/Analysis/array-struct.c6
-rw-r--r--test/Analysis/casts.c19
-rw-r--r--test/Analysis/cfref_rdar6080742.c18
-rw-r--r--test/Analysis/complex.c2
-rw-r--r--test/Analysis/dead-stores.c171
-rw-r--r--test/Analysis/dead-stores.cpp19
-rw-r--r--test/Analysis/exercise-ps.c2
-rw-r--r--test/Analysis/misc-ps-basic-store.m14
-rw-r--r--test/Analysis/misc-ps-region-store-i386.m14
-rw-r--r--test/Analysis/misc-ps-region-store-x86_64.m14
-rw-r--r--test/Analysis/misc-ps-region-store.m243
-rw-r--r--test/Analysis/misc-ps.m410
-rw-r--r--test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m3
-rw-r--r--test/Analysis/no-outofbounds.c12
-rw-r--r--test/Analysis/null-deref-ps.c39
-rw-r--r--test/Analysis/outofbound.c1
-rw-r--r--test/Analysis/pr4209.m3
-rw-r--r--test/Analysis/rdar-6442306-1.m1
-rw-r--r--test/Analysis/rdar-6540084.m1
-rw-r--r--test/Analysis/rdar-6541136-region.c7
-rw-r--r--test/Analysis/rdar-6562655.m6
-rw-r--r--test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m3
-rw-r--r--test/Analysis/rdar-7168531.m19
-rw-r--r--test/Analysis/region-1.m1
-rw-r--r--test/Analysis/region-only-test.c2
-rw-r--r--test/Analysis/retain-release-gc-only.m186
-rw-r--r--test/Analysis/retain-release-region-store.m24
-rw-r--r--test/Analysis/retain-release.m439
-rw-r--r--test/Analysis/security-syntax-checks.m91
-rw-r--r--test/Analysis/uninit-vals-ps-region.c18
-rw-r--r--test/Analysis/uninit-vals-ps.c50
-rw-r--r--test/Analysis/uninit-vals.c2
-rw-r--r--test/Analysis/unions-region.m41
-rw-r--r--test/Analysis/unused-ivars.m45
40 files changed, 1811 insertions, 146 deletions
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m
index dfc736627bfc..557e7e8f915c 100644
--- a/test/Analysis/CFDateGC.m
+++ b/test/Analysis/CFDateGC.m
@@ -1,6 +1,6 @@
-// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -analyzer-constraints=basic %s &&
-// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -analyzer-constraints=range %s &&
-// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc -disable-free %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc -disable-free %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s
@@ -25,7 +25,7 @@ extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
typedef struct objc_object {} *id;
typedef signed char BOOL;
-static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {}
+static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) { return 0; }
@protocol NSObject - (BOOL)isEqual:(id)object;
- (oneway void)release;
- (id)retain;
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
index 779b865aff8c..5f92594f30d8 100644
--- a/test/Analysis/CheckNSError.m
+++ b/test/Analysis/CheckNSError.m
@@ -24,7 +24,7 @@ extern NSString * const NSXMLParserErrorDomain ;
@end
@implementation A
-- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occured.}}
+- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}}
*error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
}
@@ -37,7 +37,7 @@ extern NSString * const NSXMLParserErrorDomain ;
struct __CFError {};
typedef struct __CFError* CFErrorRef;
-void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occured.}}
+void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}}
*error = 0; // expected-warning {{Potential null dereference.}}
}
diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m
index c4d4c22540f2..801620a181bf 100644
--- a/test/Analysis/NSPanel.m
+++ b/test/Analysis/NSPanel.m
@@ -28,7 +28,7 @@ typedef struct _NSZone NSZone;
@end
typedef float CGFloat;
typedef struct _NSPoint {} NSRect;
-static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) {}
+static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) { NSRect r; return r; }
typedef struct {} NSFastEnumerationState;
@protocol NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
index b707071990f8..0ba3cda6d580 100644
--- a/test/Analysis/NSString.m
+++ b/test/Analysis/NSString.m
@@ -1,9 +1,7 @@
// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
-// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s
-
-
-// NOTWORK: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s &&
-// NOTWORK: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s &&
+// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s &&
+// RUN: clang-cc -triple i386-pc-linux-gnu -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from
@@ -157,6 +155,7 @@ NSString* f11(CFDictionaryRef dict, const char* key) {
if (s) {
[s release];
}
+ return 0;
}
// Test case for passing a tracked object by-reference to a function we
@@ -285,6 +284,12 @@ void testOSCompareAndSwap32Barrier() {
[old release];
}
+int testOSCompareAndSwap32Barrier_id(Class myclass, id xclass) {
+ if (OSAtomicCompareAndSwap32Barrier(0, (int32_t) myclass, (int32_t*) &xclass))
+ return 1;
+ return 0;
+}
+
void test_objc_atomicCompareAndSwap() {
NSString *old = 0;
NSString *s = [[NSString alloc] init]; // no-warning
diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m
index 7bc90b8d03e0..0cb3dea8ea86 100644
--- a/test/Analysis/PR2978.m
+++ b/test/Analysis/PR2978.m
@@ -55,6 +55,7 @@
[self setW:@"newW"]; // This will release '_W', but retain the new value
self.O = 0; // no-warning
[super dealloc];
+ return 0;
}
@end
diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m
index 20d4b5b96059..bbc1377b0415 100644
--- a/test/Analysis/PR3991.m
+++ b/test/Analysis/PR3991.m
@@ -43,6 +43,7 @@ typedef struct _NSZone NSZone;
- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex;
- (NSURL *)folderFeedURL;
@end @implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner {
+ return 0;
}
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index da7df4b28e30..d6b6076a14b2 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -1,7 +1,5 @@
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
-// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s
-
-// RegionStore now has an infinite recursion with this test case.
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
@@ -145,7 +143,7 @@ void f15() {
int a[10];
bar(a);
if (a[1]) // no-warning
- 1;
+ (void)1;
}
struct s3 p[1];
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 5e4222bc84be..ae51ffb69aa5 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -1,9 +1,16 @@
-// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region --verify %s
+// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref -analyzer-store=region --verify %s
// Test if the 'storage' region gets properly initialized after it is cast to
// 'struct sockaddr *'.
-#include <sys/socket.h>
+typedef unsigned char __uint8_t;
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_socklen_t;
+typedef __uint8_t sa_family_t;
+typedef __darwin_socklen_t socklen_t;
+struct sockaddr { sa_family_t sa_family; };
+struct sockaddr_storage {};
+
void f(int sock) {
struct sockaddr_storage storage;
struct sockaddr* sockaddr = (struct sockaddr*)&storage;
@@ -19,14 +26,14 @@ struct s {
struct s *value;
};
-int f1(struct s **pval) {
+void f1(struct s **pval) {
int *tbool = ((void*)0);
struct s *t = *pval;
pval = &(t->value);
- tbool = (int *)pval; // Should record the cast-to type here.
+ tbool = (int *)pval; // use the cast-to type 'int *' to create element region.
char c = (unsigned char) *tbool; // Should use cast-to type to create symbol.
- if (*tbool == -1)
- 3;
+ if (*tbool == -1) // here load the element region with the correct type 'int'
+ (void)3;
}
void f2(const char *str) {
diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c
index 5d957615d0dd..9bbaf9b5ae06 100644
--- a/test/Analysis/cfref_rdar6080742.c
+++ b/test/Analysis/cfref_rdar6080742.c
@@ -44,15 +44,15 @@ Boolean DebugDisplayOSStatusMsg(OSStatus status, const char *statusStr,
#define AssertNoErr(err){ DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__); }
#define RequireNoErr(err, action){ if( DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__) ) { action }}
-void DebugStop(const char *format,...); /* Not an abort function. */
+void DebugStop(const char *format,...); /* Not an abort function. */
int main(int argc, char *argv[]) {
- CFStringRef cfString;
- OSStatus status = noErr;
- cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8);
- RequireAction(cfString != 0, return memFullErr;) //no - warning
- printf("cfstring %p\n", cfString);
-Exit:
- CFRelease(cfString);
- return 0;
+ CFStringRef cfString;
+ OSStatus status = noErr;
+ cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8);
+ RequireAction(cfString != 0, return memFullErr;) //no - warning
+ printf("cfstring %p\n", cfString);
+ Exit:
+ CFRelease(cfString);
+ return 0;
}
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
index cef624577a6d..3633b2148413 100644
--- a/test/Analysis/complex.c
+++ b/test/Analysis/complex.c
@@ -5,7 +5,7 @@
#include <stdint.h>
-int f1(int * p) {
+void f1(int * p) {
// This branch should be infeasible
// because __imag__ p is 0.
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 6d3b7e6f540d..c4ff7fa0e860 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -57,7 +57,7 @@ int f7(int *p) {
int f8(int *p) {
extern int *baz();
- if (p = baz()) // expected-warning{{Although the value}}
+ if ((p = baz())) // expected-warning{{Although the value}}
return 1;
return 0;
}
@@ -129,14 +129,15 @@ int f16(int x) {
}
// Self-assignments should not be flagged as dead stores.
-int f17() {
+void f17() {
int x = 1;
x = x; // no-warning
}
// <rdar://problem/6506065>
// The values of dead stores are only "consumed" in an enclosing expression
-// what that value is actually used. In other words, don't say "Although the value stored to 'x' is used...".
+// what that value is actually used. In other words, don't say "Although the
+// value stored to 'x' is used...".
int f18() {
int x = 0; // no-warning
if (1)
@@ -171,3 +172,167 @@ void f20(void) {
#pragma unused(x)
}
+void halt() __attribute__((noreturn));
+int f21() {
+ int x = 4;
+
+ ++x; // expected-warning{{never read}}
+ if (1) {
+ halt();
+ (void)x;
+ }
+ return 1;
+}
+
+int j;
+void f22() {
+ int x = 4;
+ int y1 = 4;
+ int y2 = 4;
+ int y3 = 4;
+ int y4 = 4;
+ int y5 = 4;
+ int y6 = 4;
+ int y7 = 4;
+ int y8 = 4;
+ int y9 = 4;
+ int y10 = 4;
+ int y11 = 4;
+ int y12 = 4;
+ int y13 = 4;
+ int y14 = 4;
+ int y15 = 4;
+ int y16 = 4;
+ int y17 = 4;
+ int y18 = 4;
+ int y19 = 4;
+ int y20 = 4;
+
+ ++x; // expected-warning{{never read}}
+ ++y1;
+ ++y2;
+ ++y3;
+ ++y4;
+ ++y5;
+ ++y6;
+ ++y7;
+ ++y8;
+ ++y9;
+ ++y10;
+ ++y11;
+ ++y12;
+ ++y13;
+ ++y14;
+ ++y15;
+ ++y16;
+ ++y17;
+ ++y18;
+ ++y19;
+ ++y20;
+
+ switch (j) {
+ case 1:
+ if (0)
+ (void)x;
+ if (1) {
+ (void)y1;
+ return;
+ }
+ (void)x;
+ break;
+ case 2:
+ if (0)
+ (void)x;
+ else {
+ (void)y2;
+ return;
+ }
+ (void)x;
+ break;
+ case 3:
+ if (1) {
+ (void)y3;
+ return;
+ } else
+ (void)x;
+ (void)x;
+ break;
+ case 4:
+ 0 ? : ((void)y4, ({ return; }));
+ (void)x;
+ break;
+ case 5:
+ 1 ? : (void)x;
+ 0 ? (void)x : ((void)y5, ({ return; }));
+ (void)x;
+ break;
+ case 6:
+ 1 ? ((void)y6, ({ return; })) : (void)x;
+ (void)x;
+ break;
+ case 7:
+ (void)(0 && x);
+ (void)y7;
+ (void)(0 || (y8, ({ return; }), 1));
+ (void)x;
+ break;
+ case 8:
+ (void)(1 && (y9, ({ return; }), 1));
+ (void)x;
+ break;
+ case 9:
+ (void)(1 || x);
+ (void)y10;
+ break;
+ case 10:
+ while (0) {
+ (void)x;
+ }
+ (void)y11;
+ break;
+ case 11:
+ while (1) {
+ (void)y12;
+ }
+ (void)x;
+ break;
+ case 12:
+ do {
+ (void)y13;
+ } while (0);
+ (void)y14;
+ break;
+ case 13:
+ do {
+ (void)y15;
+ } while (1);
+ (void)x;
+ break;
+ case 14:
+ for (;;) {
+ (void)y16;
+ }
+ (void)x;
+ break;
+ case 15:
+ for (;1;) {
+ (void)y17;
+ }
+ (void)x;
+ break;
+ case 16:
+ for (;0;) {
+ (void)x;
+ }
+ (void)y18;
+ break;
+ case 17:
+ __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
+ (void)x;
+ break;
+ case 19:
+ __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
+ (void)x;
+ break;
+ }
+}
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
new file mode 100644
index 000000000000..9ddb7979ca69
--- /dev/null
+++ b/test/Analysis/dead-stores.cpp
@@ -0,0 +1,19 @@
+// RUN: clang-cc -analyze -warn-dead-stores -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -warn-dead-stores -verify %s
+
+int j;
+void f1() {
+ int x = 4;
+
+ ++x; // expected-warning{{never read}}
+
+ switch (j) {
+ case 1:
+ throw 1;
+ (void)x;
+ break;
+ }
+}
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index c309349ab3a9..1e31b1888e1f 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -5,7 +5,7 @@
// (i.e., no assertions or crashes).
-static const char * f1(const char *x, char *y) {
+static void f1(const char *x, char *y) {
while (*x != 0) {
*y++ = *x++;
}
diff --git a/test/Analysis/misc-ps-basic-store.m b/test/Analysis/misc-ps-basic-store.m
index 1207f8663e90..c6ae20c86a36 100644
--- a/test/Analysis/misc-ps-basic-store.m
+++ b/test/Analysis/misc-ps-basic-store.m
@@ -19,3 +19,17 @@ void checkaccess_union() {
).__i))) & 0xff00) >> 8) == 1)
ret = 1;
}
+
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively. See the companion test
+// in 'misc-ps-region-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+ int a = *x;
+ int b = *x;
+ if (a != b) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // expected-warning{{null}}
+ }
+}
+
diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m
new file mode 100644
index 000000000000..c2c4d5b9413c
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-i386.m
@@ -0,0 +1,14 @@
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
+
+// Here is a case where a pointer is treated as integer, invalidated as an
+// integer, and then used again as a pointer. This test just makes sure
+// we don't crash.
+typedef unsigned uintptr_t;
+void test_pointer_invalidated_as_int_aux(uintptr_t* ptr);
+void test_pointer_invalidated_as_int() {
+ void *x;
+ test_pointer_invalidated_as_int_aux((uintptr_t*) &x);
+ // Here we have a pointer to integer cast.
+ uintptr_t y = (uintptr_t) x;
+}
+
diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m
new file mode 100644
index 000000000000..154ffaf3a003
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-x86_64.m
@@ -0,0 +1,14 @@
+// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
+
+// Here is a case where a pointer is treated as integer, invalidated as an
+// integer, and then used again as a pointer. This test just makes sure
+// we don't crash.
+typedef unsigned long uintptr_t;
+void test_pointer_invalidated_as_int_aux(uintptr_t* ptr);
+void test_pointer_invalidated_as_int() {
+ void *x;
+ test_pointer_invalidated_as_int_aux((uintptr_t*) &x);
+ // Here we have a pointer to integer cast.
+ uintptr_t y = (uintptr_t) x;
+}
+
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 8c8815ea63eb..e849042b3d3d 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1,4 +1,5 @@
-// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s &&
+// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
typedef struct objc_selector *SEL;
typedef signed char BOOL;
@@ -31,10 +32,12 @@ extern NSString * const NSConnectionReplyMode;
// PR 2948 (testcase; crash on VisitLValue for union types)
// http://llvm.org/bugs/show_bug.cgi?id=2948
-
void checkaccess_union() {
int ret = 0, status;
- if (((((__extension__ (((union { // expected-warning {{ Branch condition evaluates to an uninitialized value.}}
+ // Since RegionStore doesn't handle unions yet,
+ // this branch condition won't be triggered
+ // as involving an uninitialized value.
+ if (((((__extension__ (((union { // no-warning
__typeof (status) __in; int __i;}
)
{
@@ -43,7 +46,6 @@ void checkaccess_union() {
ret = 1;
}
-
// Check our handling of fields being invalidated by function calls.
struct test2_struct { int x; int y; char* s; };
void test2_helper(struct test2_struct* p);
@@ -68,3 +70,236 @@ char test2() {
return 'a';
}
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively. RegionStore handles
+// it correctly. See the companion test in 'misc-ps-basic-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+ int a = *x;
+ int b = *x;
+ if (a != b) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+}
+
+// This is a modified test from 'misc-ps.m'. Here we have the extra
+// NULL dereferences which are pruned out by RegionStore's symbolic reasoning
+// of fields.
+typedef struct _BStruct { void *grue; } BStruct;
+void testB_aux(void *ptr);
+
+void testB(BStruct *b) {
+ {
+ int *__gruep__ = ((int *)&((b)->grue));
+ int __gruev__ = *__gruep__;
+ int __gruev2__ = *__gruep__;
+ if (__gruev__ != __gruev2__) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+
+ testB_aux(__gruep__);
+ }
+ {
+ int *__gruep__ = ((int *)&((b)->grue));
+ int __gruev__ = *__gruep__;
+ int __gruev2__ = *__gruep__;
+ if (__gruev__ != __gruev2__) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+
+ if (~0 != __gruev__) {}
+ }
+}
+
+void testB_2(BStruct *b) {
+ {
+ int **__gruep__ = ((int **)&((b)->grue));
+ int *__gruev__ = *__gruep__;
+ testB_aux(__gruep__);
+ }
+ {
+ int **__gruep__ = ((int **)&((b)->grue));
+ int *__gruev__ = *__gruep__;
+ if ((int*)~0 != __gruev__) {}
+ }
+}
+
+// This test case is a reduced case of a caching bug discovered by an
+// assertion failure in RegionStoreManager::BindArray. Essentially the
+// DeclStmt is evaluated twice, but on the second loop iteration the
+// engine caches out. Previously a false transition would cause UnknownVal
+// to bind to the variable, firing an assertion failure. This bug was fixed
+// in r76262.
+void test_declstmt_caching() {
+again:
+ {
+ const char a[] = "I like to crash";
+ goto 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) {
+ int *p = s->p;
+ if (!p) {
+ // Infeasible
+ int *dead = 0;
+ *dead = 0xDEADBEEF; // no-warning
+ }
+ }
+}
+
+// Test pointers increment correctly.
+void f() {
+ int a[2];
+ a[1] = 3;
+ int *p = a;
+ p++;
+ if (*p != 3) {
+ int *q = 0;
+ *q = 3; // no-warning
+ }
+}
+
+// <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;
+};
+int rdar_test_7185607() {
+ struct test_7185607 s; // Uninitialized.
+ *((unsigned *) &s) = 0U;
+ 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;
+ CGFloat height;
+} NSSize;
+
+CGFloat rdar7242006_negative(CGFloat x) {
+ NSSize y;
+ 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;
+ if (*x)
+ return;
+ int *p = 0; // This is unreachable.
+ *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]) {
+ int B[2*32];
+ int *b;
+ unsigned int *a;
+ int x = 0;
+
+ int n;
+
+ a = A;
+ b = B;
+
+ n = *a++;
+ if (n)
+ *b++ = rdar_7249327_aux();
+
+ a = A;
+ b = B;
+
+ n = *a++;
+ if (n)
+ 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) {
+ int x;
+ struct doodad_6914474 d;
+ d.v = &x;
+ prod_6914474(&d);
+ return x; // no-warning
+}
+
+// Test invalidation of a single field.
+struct s_test_field_invalidate {
+ int x;
+};
+extern void test_invalidate_field(int *x);
+int test_invalidate_field_test() {
+ struct s_test_field_invalidate y;
+ test_invalidate_field(&y.x);
+ return y.x; // no-warning
+}
+int test_invalidate_field_test_positive() {
+ struct s_test_field_invalidate y;
+ return y.x; // expected-warning{{garbage}}
+}
+
+// This test case illustrates how a typeless array of bytes casted to a
+// struct should be treated as initialized. RemoveDeadBindings previously
+// had a bug that caused 'x' to lose its default symbolic value after the
+// assignment to 'p', thus causing 'p->z' to evaluate to "undefined".
+struct ArrayWrapper { unsigned char y[16]; };
+struct WrappedStruct { unsigned z; };
+
+int test_handle_array_wrapper() {
+ struct ArrayWrapper x;
+ test_handle_array_wrapper(&x);
+ struct WrappedStruct *p = (struct WrappedStruct*) x.y;
+ 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 *)"????"))
+ return 1;
+ 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;
+
+ unsigned short *p = (unsigned short*) data;
+ unsigned short *q = p + (n / 2);
+
+ if (p < q) {
+ // If we reach here, 'p' cannot be null. If 'p' is null, then 'n' must
+ // be '0', meaning that this branch is not feasible.
+ *p = *q; // no-warning
+ }
+}
+
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index ea41b5bb2f35..10e5823c206c 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -1,24 +1,43 @@
-// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s &&
+// NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued.
+// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -fobjc-gc -analyzer-constraints=basic --verify -fblocks %s &&
// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s &&
// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s &&
// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s
+typedef struct objc_ivar *Ivar;
typedef struct objc_selector *SEL;
typedef signed char BOOL;
typedef int NSInteger;
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
+@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)autorelease;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} - (id)init; @end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)allocWithZone:(NSZone *)zone;
+@end
extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
- (NSUInteger)length;
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
@end extern NSString * const NSBundleDidLoadNotification;
+@interface NSValue : NSObject <NSCopying, NSCoding>
+- (void)getValue:(void *)value;
+@end
+@interface NSNumber : NSValue
+- (char)charValue;
+- (id)initWithBool:(BOOL)value;
+@end
@interface NSAssertionHandler : NSObject {}
+ (NSAssertionHandler *)currentHandler;
- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
@@ -144,7 +163,7 @@ void pr3422() {
}
// PR 3543 (handle empty statement expressions)
-int pr_3543(void) {
+void pr_3543(void) {
({});
}
@@ -295,4 +314,381 @@ void rdar_7027684(int x, int y) {
(rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0);
}
+// Test that we handle casts of string literals to arbitrary types.
+unsigned const char *string_literal_test1() {
+ return (const unsigned char*) "hello";
+}
+
+const float *string_literal_test2() {
+ return (const float*) "hello";
+}
+
+// Test that we handle casts *from* incomplete struct types.
+extern const struct _FooAssertStruct _cmd;
+void test_cast_from_incomplete_struct_aux(volatile const void *x);
+void test_cast_from_incomplete_struct() {
+ test_cast_from_incomplete_struct_aux(&_cmd);
+}
+
+// Test for <rdar://problem/7034511>
+// "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc'
+// when 'T' is a pointer"
+//
+// Previously this case would crash.
+void test_rdar_7034511(NSArray *y) {
+ NSObject *x;
+ for (x in y) {}
+ if (x == ((void*) 0)) {}
+}
+
+// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer
+// types. This was previously causing a crash in CastRegion.
+void handle_funcptr_voidptr_casts() {
+ void **ptr;
+ typedef void *PVOID;
+ typedef void *PCHAR;
+ typedef long INT_PTR, *PINT_PTR;
+ typedef INT_PTR (*FARPROC)();
+ FARPROC handle_funcptr_voidptr_casts_aux();
+ PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x);
+ PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x);
+
+ ptr = (void**) handle_funcptr_voidptr_casts_aux();
+ handle_funcptr_voidptr_casts_aux_2(ptr);
+ handle_funcptr_voidptr_casts_aux_3(ptr);
+}
+
+// RegionStore::Retrieve previously crashed on this example. This example
+// was previously in the test file 'xfail_regionstore_wine_crash.c'.
+void testA() {
+ long x = 0;
+ char *y = (char *) &x;
+ if (!*y)
+ return;
+}
+
+// RegionStoreManager previously crashed on this example. The problem is that
+// the value bound to the field of b->grue after the call to testB_aux is
+// a symbolic region. The second '*__gruep__' involves performing a load
+// from a 'int*' that really is a 'void**'. The loaded location must be
+// implicitly converted to an integer that wraps a location. Previosly we would
+// get a crash here due to an assertion failure.
+typedef struct _BStruct { void *grue; } BStruct;
+void testB_aux(void *ptr);
+void testB(BStruct *b) {
+ {
+ int *__gruep__ = ((int *)&((b)->grue));
+ int __gruev__ = *__gruep__;
+ testB_aux(__gruep__);
+ }
+ {
+ int *__gruep__ = ((int *)&((b)->grue));
+ int __gruev__ = *__gruep__;
+ if (~0 != __gruev__) {}
+ }
+}
+
+void test_trivial_symbolic_comparison(int *x) {
+ int test_trivial_symbolic_comparison_aux();
+ int a = test_trivial_symbolic_comparison_aux();
+ int b = a;
+ if (a != b) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+
+ a = a == 1;
+ b = b == 1;
+ if (a != b) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+}
+
+// Test for:
+// <rdar://problem/7062158> false positive null dereference due to
+// BasicStoreManager not tracking *static* globals
+//
+// This just tests the proper tracking of symbolic values for globals (both
+// static and non-static).
+//
+static int* x_rdar_7062158;
+void rdar_7062158() {
+ int *current = x_rdar_7062158;
+ if (current == x_rdar_7062158)
+ return;
+
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+
+int* x_rdar_7062158_2;
+void rdar_7062158_2() {
+ int *current = x_rdar_7062158_2;
+ if (current == x_rdar_7062158_2)
+ return;
+
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+
+// This test reproduces a case for a crash when analyzing ClamAV using
+// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because
+// it isn't doing anything smart about arrays). The problem is that on the
+// second line, 'p = &p[i]', p is assigned an ElementRegion whose index
+// is a 16-bit integer. On the third line, a new ElementRegion is created
+// based on the previous region, but there the region uses a 32-bit integer,
+// resulting in a clash of values (an assertion failure at best). We resolve
+// this problem by implicitly converting index values to 'int' when the
+// ElementRegion is created.
+unsigned char test_array_index_bitwidth(const unsigned char *p) {
+ unsigned short i = 0;
+ for (i = 0; i < 2; i++) p = &p[i];
+ return p[i+1];
+}
+
+// This case tests that CastRegion handles casts involving BlockPointerTypes.
+// It should not crash.
+void test_block_cast() {
+ id test_block_cast_aux();
+ (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}}
+}
+
+// Test comparison of 'id' instance variable to a null void* constant after
+// performing an OSAtomicCompareAndSwap32Barrier.
+// This previously was a crash in RegionStoreManager.
+@interface TestIdNull {
+ id x;
+}
+-(int)foo;
+@end
+@implementation TestIdNull
+-(int)foo {
+ OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x);
+ if (x == (void*) 0) { return 0; }
+ return 1;
+}
+@end
+
+// PR 4594 - This was a crash when handling casts in SimpleSValuator.
+void PR4594() {
+ char *buf[1];
+ char **foo = buf;
+ *foo = "test";
+}
+
+// Test invalidation logic where an integer is casted to an array with a
+// different sign and then invalidated.
+void test_invalidate_cast_int() {
+ void test_invalidate_cast_int_aux(unsigned *i);
+ signed i;
+ test_invalidate_cast_int_aux((unsigned*) &i);
+ if (i < 0)
+ return;
+}
+
+// Reduced from a crash involving the cast of an Objective-C symbolic region to
+// 'char *'
+static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) {
+ return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease];
+}
+
+// Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero.
+// This resulted from not properly handling region casts to 'const void*'.
+void test_cast_const_voidptr() {
+ char x[10];
+ char *p = &x[1];
+ const void* q = p;
+}
+
+// Reduced from a crash when analyzing Wine. This test handles loads from
+// function addresses.
+typedef long (*FARPROC)();
+FARPROC test_load_func(FARPROC origfun) {
+ if (!*(unsigned char*) origfun)
+ return origfun;
+ return 0;
+}
+
+// Test passing-by-value an initialized struct variable.
+struct test_pass_val {
+ int x;
+ int y;
+};
+void test_pass_val_aux(struct test_pass_val s);
+void test_pass_val() {
+ struct test_pass_val s;
+ s.x = 1;
+ s.y = 2;
+ test_pass_val_aux(s);
+}
+
+// This is a reduced test case of a false positive that previously appeared
+// in RegionStoreManager. Previously the array access resulted in dereferencing
+// an undefined value.
+int test_array_compound(int *q, int *r, int *z) {
+ int *array[] = { q, r, z };
+ int j = 0;
+ for (unsigned i = 0; i < 3 ; ++i)
+ if (*array[i]) ++j; // no-warning
+ return j;
+}
+
+// This test case previously crashed with -analyzer-store=basic because the
+// symbolic value stored in 'x' wouldn't be implicitly casted to a signed value
+// during the comparison.
+int rdar_7124210(unsigned int x) {
+ enum { SOME_CONSTANT = 123 };
+ int compare = ((signed) SOME_CONSTANT) == *((signed *) &x);
+ return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint.
+}
+
+void pr4781(unsigned long *raw1) {
+ unsigned long *cook, *raw0;
+ unsigned long dough[32];
+ int i;
+ cook = dough;
+ for( i = 0; i < 16; i++, raw1++ ) {
+ raw0 = raw1++;
+ *cook = (*raw0 & 0x00fc0000L) << 6;
+ *cook |= (*raw0 & 0x00000fc0L) << 10;
+ }
+}
+
+// <rdar://problem/7185647> - 'self' should be treated as being non-null
+// upon entry to an objective-c method.
+@interface RDar7185647
+- (id)foo;
+@end
+@implementation RDar7185647
+- (id) foo {
+ if (self)
+ return self;
+ *((int *) 0x0) = 0xDEADBEEF; // no-warning
+ return self;
+}
+@end
+
+// Test reasoning of __builtin_offsetof;
+struct test_offsetof_A {
+ int x;
+ int y;
+};
+struct test_offsetof_B {
+ int w;
+ int z;
+};
+void test_offsetof_1() {
+ if (__builtin_offsetof(struct test_offsetof_A, x) ==
+ __builtin_offsetof(struct test_offsetof_B, w))
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_2() {
+ if (__builtin_offsetof(struct test_offsetof_A, y) ==
+ __builtin_offsetof(struct test_offsetof_B, z))
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_3() {
+ if (__builtin_offsetof(struct test_offsetof_A, y) -
+ __builtin_offsetof(struct test_offsetof_A, x)
+ ==
+ __builtin_offsetof(struct test_offsetof_B, z) -
+ __builtin_offsetof(struct test_offsetof_B, w))
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+void test_offsetof_4() {
+ if (__builtin_offsetof(struct test_offsetof_A, y) ==
+ __builtin_offsetof(struct test_offsetof_B, w))
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+}
+
+// <rdar://problem/6829164> "nil receiver" false positive: make tracking
+// of the MemRegion for 'self' path-sensitive
+@interface RDar6829164 : NSObject {
+ double x; int y;
+}
+- (id) init;
+@end
+
+id rdar_6829164_1();
+double rdar_6829164_2();
+
+@implementation RDar6829164
+- (id) init {
+ if((self = [super init]) != 0) {
+ id z = rdar_6829164_1();
+ y = (z != 0);
+ if (y)
+ x = rdar_6829164_2();
+ }
+ return self;
+}
+@end
+
+// <rdar://problem/7242015> - Invalidate values passed-by-reference
+// to functions when the pointer to the value is passed as an integer.
+void test_7242015_aux(unsigned long);
+int rdar_7242015() {
+ int x;
+ test_7242015_aux((unsigned long) &x); // no-warning
+ return x; // Previously we return and uninitialized value when
+ // using RegionStore.
+}
+
+// <rdar://problem/7242006> [RegionStore] compound literal assignment with
+// floats not honored
+CGFloat rdar7242006(CGFloat x) {
+ NSSize y = (NSSize){x, 10};
+ return y.width; // no-warning
+}
+
+// PR 4988 - This test exhibits a case where a function can be referenced
+// when not explicitly used in an "lvalue" context (as far as the analyzer is
+// concerned). This previously triggered a crash due to an invalid assertion.
+void pr_4988(void) {
+ pr_4988; // expected-warning{{expression result unused}}
+}
+
+// <rdar://problem/7152418> - A 'signed char' is used as a flag, which is
+// implicitly converted to an int.
+void *rdar7152418_bar();
+@interface RDar7152418 {
+ signed char x;
+}
+-(char)foo;
+@end;
+@implementation RDar7152418
+-(char)foo {
+ char *p = 0;
+ void *result = 0;
+ if (x) {
+ result = rdar7152418_bar();
+ p = "hello";
+ }
+ if (!result) {
+ result = rdar7152418_bar();
+ if (result && x)
+ return *p; // no-warning
+ }
+ 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) {
+ while (1) {
+ if (x == ((signed char) 0)) {}
+ }
+}
+
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index 9a64b3001e16..87faab6bfbac 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -1,4 +1,5 @@
-// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify &&
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s -verify
@interface MyClass {}
- (void *)voidPtrM;
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
new file mode 100644
index 000000000000..94052806f0aa
--- /dev/null
+++ b/test/Analysis/no-outofbounds.c
@@ -0,0 +1,12 @@
+// RUN: clang-cc -checker-cfref -analyze -analyzer-store=basic -verify %s &&
+// RUN: clang-cc -checker-cfref -analyze -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// This file tests cases where we should not flag out-of-bounds warnings.
+//===----------------------------------------------------------------------===//
+
+void f() {
+ long x = 0;
+ char *y = (char*) &x;
+ char c = y[0] + y[1] + y[2]; // no-warning
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 6e2074146c30..f37b4416f2a1 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,10 +1,16 @@
-// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic &&
-// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic &&
-// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s &&
-// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic &&
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic &&
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s &&
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
-#include<stdint.h>
-#include <assert.h>
+typedef unsigned uintptr_t;
+
+extern void __assert_fail (__const char *__assertion, __const char *__file,
+ unsigned int __line, __const char *__function)
+ __attribute__ ((__noreturn__));
+
+#define assert(expr) \
+ ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
void f1(int *p) {
if (p) *p = 1;
@@ -72,6 +78,7 @@ int f4_b() {
else return; // expected-warning {{non-void function 'f4_b' should return a value}}
*p += 10; // expected-warning{{Dereference of null pointer}}
+ return 0;
}
@@ -102,6 +109,15 @@ int f6c(int *p, int *q) {
: bar3(p, 2, q); // no-warning
}
+void f6d(int *p) {
+ bar(p, 0);
+ // At this point, 'p' cannot be null.
+ if (!p) {
+ int *q = 0;
+ *q = 0xDEADBEEF; // no-warning
+ }
+}
+
int* qux();
int f7(int x) {
@@ -160,7 +176,7 @@ int* f7c2(int *x) {
}
-int f8(int *p, int *q) {
+void f8(int *p, int *q) {
if (!p)
if (p)
*p = 1; // no-warning
@@ -262,4 +278,13 @@ void f13() {
if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning
}
+// PR 4759 - Attribute non-null checking by the analyzer was not correctly
+// handling pointer values that were undefined.
+void pr4759_aux(int *p) __attribute__((nonnull));
+
+void pr4759() {
+ int *p;
+ pr4759_aux(p); // expected-warning{{undefined}}
+}
+
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
index 527a311d2b7d..568f14329e9b 100644
--- a/test/Analysis/outofbound.c
+++ b/test/Analysis/outofbound.c
@@ -1,4 +1,5 @@
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
+// XFAIL
char f1() {
char* s = "abcd";
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
index 7d7d8fc5a157..991d0d68f704 100644
--- a/test/Analysis/pr4209.m
+++ b/test/Analysis/pr4209.m
@@ -1,4 +1,4 @@
-// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -verify %s &&
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-store=region -verify %s
// This test case was crashing due to how CFRefCount.cpp resolved the
@@ -56,6 +56,7 @@ CMProfileLocation;
- (GSEbayCategory *) parent;
- (GSEbayCategory*) subcategoryWithID:(int) inID;
@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent {
+ return 0;
}
- (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories {
GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]];
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
index 15d349884093..bfda115360e4 100644
--- a/test/Analysis/rdar-6442306-1.m
+++ b/test/Analysis/rdar-6442306-1.m
@@ -28,4 +28,5 @@ __Beeble_check__Request__SetPortalSize_t(__attribute__((__unused__)) __Request__
}
while (0);
}
+ return 0;
}
diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m
index 18ab038f6e2e..cfe522074ed3 100644
--- a/test/Analysis/rdar-6540084.m
+++ b/test/Analysis/rdar-6540084.m
@@ -32,5 +32,6 @@ typedef struct {} TazVersion;
}
}
}
+ while (1) {}
}
@end
diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c
index 1e7a2d974bc4..e2779e8d914f 100644
--- a/test/Analysis/rdar-6541136-region.c
+++ b/test/Analysis/rdar-6541136-region.c
@@ -13,7 +13,10 @@ void foo( void )
struct load_wine *cmd = (void*) &wonky[1];
cmd = cmd;
char *p = (void*) &wonky[1];
- *p = 1;
+ *p = 1; // no-warning
kernel_tea_cheese_t *q = &wonky[1];
- kernel_tea_cheese_t r = *q; // expected-warning{{out-of-bound memory position}}
+ // This test case tests both the RegionStore logic (doesn't crash) and
+ // the out-of-bounds checking. We don't expect the warning for now since
+ // out-of-bound checking is temporarily disabled.
+ kernel_tea_cheese_t r = *q; // eventually-warning{{out-of-bound memory position}}
}
diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m
index 581d6eacf085..3c1c281a830d 100644
--- a/test/Analysis/rdar-6562655.m
+++ b/test/Analysis/rdar-6562655.m
@@ -1,4 +1,5 @@
-// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic -verify %s
+// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region -verify %s
//
// This test case mainly checks that the retain/release checker doesn't crash
// on this file.
@@ -51,7 +52,7 @@ typedef struct _NSRunArrayItem {
@end
@implementation Bar
static Baz Qux = 0;
-- (id)copyWithZone:(NSZone *)zone {}
+- (id)copyWithZone:(NSZone *)zone { return 0; }
- (void)encodeWithCoder:(NSCoder *)coder {}
@end
@implementation Bar (BarBotnet)
@@ -59,5 +60,6 @@ static Baz Qux = 0;
if (!(*(BarAuxiliary **)&self->_support)->auxCFlags.botnetIsSet) {
_cFlags.botnet = [self _initialBotnetZorg];
}
+ while (1) {}
}
@end
diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
index 5d1fa37c46a8..49ef7c381545 100644
--- a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
+++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
@@ -1,4 +1,5 @@
-// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify
+// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s -verify
typedef struct Foo { int x; } Bar;
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
new file mode 100644
index 000000000000..bdbd22d24e2c
--- /dev/null
+++ b/test/Analysis/rdar-7168531.m
@@ -0,0 +1,19 @@
+// RUN: clang-cc -analyze -checker-cfref -triple i386-apple-darwin10 -analyzer-store=region &&
+// RUN: clang-cc -analyze -checker-cfref -triple i386-apple-darwin10 -analyzer-store=basic
+
+// Note that the target triple is important for this test case. It specifies that we use the
+// fragile Objective-C ABI.
+
+@interface Foo {
+ int x;
+}
+@end
+
+@implementation Foo
+static Foo* bar(Foo *p) {
+ if (p->x)
+ return ++p; // This is only valid for the fragile ABI.
+
+ return p;
+}
+@end
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
index ed172e431e99..68a375b7126c 100644
--- a/test/Analysis/region-1.m
+++ b/test/Analysis/region-1.m
@@ -79,6 +79,7 @@ typedef NSUInteger JabaSourceLanguage;
Dos_CharacterRangeType = 0, Dos_LineRangeType = 1 }
DosTextRangeType;
@implementation JabaSCSharedDiagramViewController + (NSImage *)findImageNamed:(NSString *)name {
+ return 0;
}
- (void)revealSourceInEditor:(JabasectItem *)sectItem duperGesture:(BOOL)duperGesture {
id <EcoNamedElement> selectedElement = [sectItem representedObject];
diff --git a/test/Analysis/region-only-test.c b/test/Analysis/region-only-test.c
index 64d3fcd57b2a..8908adb1057c 100644
--- a/test/Analysis/region-only-test.c
+++ b/test/Analysis/region-only-test.c
@@ -9,5 +9,5 @@ void foo(int* p) {
if (p[0] == 1)
x = &a;
if (p[0] == 1)
- *x; // no-warning
+ (void)*x; // no-warning
}
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
index ec33a57d3303..2833b02f0771 100644
--- a/test/Analysis/retain-release-gc-only.m
+++ b/test/Analysis/retain-release-gc-only.m
@@ -1,16 +1,26 @@
-// RUN: clang-cc -analyze -checker-cfref -verify -fobjc-gc-only %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc-only %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fobjc-gc-only -verify %s
//===----------------------------------------------------------------------===//
// Header stuff.
//===----------------------------------------------------------------------===//
-typedef struct objc_class *Class;
-
typedef unsigned int __darwin_natural_t;
-typedef struct {} div_t;
-typedef unsigned long UInt32;
+typedef unsigned long uintptr_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int UInt32;
typedef signed long CFIndex;
+typedef struct {
+ CFIndex location;
+ CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+ CFRange range;
+ range.location = loc;
+ range.length = len;
+ return range;
+}
typedef const void * CFTypeRef;
typedef const struct __CFString * CFStringRef;
typedef const struct __CFAllocator * CFAllocatorRef;
@@ -26,7 +36,17 @@ typedef struct __CFArray * CFMutableArrayRef;
extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
typedef UInt32 CFStringEncoding;
enum {
kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 };
@@ -40,44 +60,96 @@ extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
typedef __darwin_natural_t natural_t;
typedef natural_t mach_port_name_t;
typedef mach_port_name_t mach_port_t;
-typedef struct {
-}
-CFRunLoopObserverContext;
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
typedef signed char BOOL;
-typedef unsigned int NSUInteger;
+typedef unsigned long NSUInteger;
@class NSString, Protocol;
extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
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;
- (id)autorelease;
+- (Class)class;
@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
@end
@interface NSObject <NSObject> {}
-- (Class)class;
-+ (id)alloc;
+ (id)allocWithZone:(NSZone *)zone;
-@end typedef float CGFloat;
++ (id)alloc;
+- (void)dealloc;
+@end
+@interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+}
+NSFastEnumerationState;
+@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end @class NSString, NSDictionary;
+@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
+@end @interface NSNumber : NSValue - (char)charValue;
+- (id)initWithInt:(int)value;
+@end @class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@end @interface NSArray (NSArrayCreation) + (id)array;
+@end @interface NSAutoreleasePool : NSObject {
+}
+- (void)drain;
+@end extern NSString * const NSBundleDidLoadNotification;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end typedef unsigned short unichar;
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
-- (const char *)UTF8String;
+- ( const char *)UTF8String;
- (id)initWithUTF8String:(const char *)nullTerminatedCString;
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
-- (id)init;
-- (void)dealloc;
-@end extern NSString * const NSCurrentLocaleDidChangeNotification ;
-@protocol NSLocking - (void)lock;
-@end extern NSString * const NSUndoManagerCheckpointNotification;
-typedef enum {
-ACL_READ_DATA = (1<<1), ACL_LIST_DIRECTORY = (1<<1), ACL_WRITE_DATA = (1<<2), ACL_ADD_FILE = (1<<2), ACL_EXECUTE = (1<<3), ACL_SEARCH = (1<<3), ACL_DELETE = (1<<4), ACL_APPEND_DATA = (1<<5), ACL_ADD_SUBDIRECTORY = (1<<5), ACL_DELETE_CHILD = (1<<6), ACL_READ_ATTRIBUTES = (1<<7), ACL_WRITE_ATTRIBUTES = (1<<8), ACL_READ_EXTATTRIBUTES = (1<<9), ACL_WRITE_EXTATTRIBUTES = (1<<10), ACL_READ_SECURITY = (1<<11), ACL_WRITE_SECURITY = (1<<12), ACL_CHANGE_OWNER = (1<<13) }
-acl_entry_id_t;
-typedef int kern_return_t;
-typedef kern_return_t mach_error_t;
+@end @class NSString, NSURL, NSError;
+@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
+@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id)aKey;
+@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+@end typedef double CGFloat;
+struct CGSize {
+};
+typedef struct CGSize CGSize;
+struct CGRect {
+};
+typedef struct CGRect CGRect;
typedef mach_port_t io_object_t;
+typedef char io_name_t[128];
+typedef io_object_t io_iterator_t;
typedef io_object_t io_service_t;
+typedef struct IONotificationPort * IONotificationPortRef;
+typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator );
+io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching );
+kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing );
+kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated));
+kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification );
+CFMutableDictionaryRef IOServiceMatching( const char * name );
+CFMutableDictionaryRef IOServiceNameMatching( const char * name );
+CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName );
+CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path );
+CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID );
typedef struct __DASession * DASessionRef;
extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
typedef struct __DADisk * DADiskRef;
@@ -85,23 +157,62 @@ extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef
extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSTask : NSObject - (id)init;
+@end typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGImage *CGImageRef;
+typedef struct CGLayer *CGLayerRef;
@interface NSResponder : NSObject <NSCoding> {
}
-@end @class NSColor, NSFont, NSNotification;
-typedef struct __CFlags {
+@end @protocol NSAnimatablePropertyContainer - (id)animator;
+@end extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder <NSAnimatablePropertyContainer> {
}
-_CFlags;
+@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
+@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+@end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
+}
+@end enum {
+NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 };
+typedef NSUInteger NSApplicationTerminateReply;
+@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
@interface NSCell : NSObject <NSCopying, NSCoding> {
}
-@end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
-@interface NSManagedObjectContext : NSObject <NSCoding, NSLocking> {
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+@interface CIImage : NSObject <NSCoding, NSCopying> {
}
-@end enum {
+typedef int CIFormat;
+@end enum {
kDAReturnSuccess = 0, kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
typedef mach_error_t DAReturn;
typedef const struct __DADissenter * DADissenterRef;
extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
-
+@interface CIContext: NSObject {
+}
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
+- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
+@end extern NSString* const QCRendererEventKey;
+@protocol QCCompositionRenderer - (NSDictionary*) attributes;
+@end @interface QCRenderer : NSObject <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end extern NSString* const QCViewDidStartRenderingNotification;
+@interface QCView : NSView <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+@end enum {
+ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, };
+@class ICDevice;
+@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device;
+@end extern NSString *const ICScannerStatusWarmingUp;
+@class ICScannerDevice;
+@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
+@end
CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef
@@ -198,6 +309,19 @@ void f5b() {
@end
//===----------------------------------------------------------------------===//
+// <rdar://problem/7174400> 'ciContext createCGImage:outputImage fromRect:' returns a retained CF object (not GC'ed)//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+void rdar_7174400(QCView *view, QCRenderer *renderer, CIContext *context,
+ NSString *str, CIImage *img, CGRect rect,
+ CIFormat form, CGColorSpaceRef cs) {
+ [view createSnapshotImageOfType:str]; // no-warning
+ [renderer createSnapshotImageOfType:str]; // no-warning
+ [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
+ [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
// Tests of ownership attributes.
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
index 66950e2190ed..7a696833f92d 100644
--- a/test/Analysis/retain-release-region-store.m
+++ b/test/Analysis/retain-release-region-store.m
@@ -1,4 +1,5 @@
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
+// XFAIL
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from
@@ -115,4 +116,27 @@ CFAbsoluteTime f4() {
}
@end
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7257223> - 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();
+ s.x = CFDateCreate(0, t); // no-warning
+ rdar_7257223_aux(&s);
+ return s.x;
+}
+
+CFDateRef rdar7257223_Create_2(void) {
+ RDar7257223 s;
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ s.x = CFDateCreate(0, t); // no-warning
+ return s.x;
+}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index da0ae801dac6..7076bb294254 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1,6 +1,12 @@
-//>>SLICER
-// RUN: clang-cc -analyze -checker-cfref -verify %s &&
-// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -verify %s &&
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -verify %s
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from Mac OS X headers:
@@ -21,6 +27,16 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned int UInt32;
typedef signed long CFIndex;
+typedef struct {
+ CFIndex location;
+ CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+ CFRange range;
+ range.location = loc;
+ range.length = len;
+ return range;
+}
typedef const void * CFTypeRef;
typedef const struct __CFString * CFStringRef;
typedef const struct __CFAllocator * CFAllocatorRef;
@@ -36,8 +52,17 @@ typedef struct __CFArray * CFMutableArrayRef;
extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
typedef const struct __CFDictionary * CFDictionaryRef;
typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
typedef UInt32 CFStringEncoding;
enum {
kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 };
@@ -53,29 +78,48 @@ typedef natural_t mach_port_name_t;
typedef mach_port_name_t mach_port_t;
typedef int kern_return_t;
typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
typedef signed char BOOL;
typedef unsigned long NSUInteger;
@class NSString, Protocol;
extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
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;
- (id)autorelease;
@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
-@end @interface NSObject <NSObject> {
-}
+@end
+@interface NSObject <NSObject> {}
+ (id)allocWithZone:(NSZone *)zone;
+ (id)alloc;
- (void)dealloc;
-@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@end
+@interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
typedef struct {
}
NSFastEnumerationState;
@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end @class NSString, NSDictionary;
+@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
+@end @interface NSNumber : NSValue - (char)charValue;
+- (id)initWithInt:(int)value;
@end @class NSString;
@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
@end @interface NSArray (NSArrayCreation) + (id)array;
@@ -90,11 +134,11 @@ typedef double NSTimeInterval;
- ( const char *)UTF8String;
- (id)initWithUTF8String:(const char *)nullTerminatedCString;
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
-@end @class NSString, NSData;
+@end @class NSString, NSURL, NSError;
@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
-@end @class NSString;
+@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
- (void)setObject:(id)anObject forKey:(id)aKey;
@@ -106,9 +150,6 @@ typedef struct CGSize CGSize;
struct CGRect {
};
typedef struct CGRect CGRect;
-@protocol NSLocking - (void)lock;
-- (id)init;
-@end @class NSURLAuthenticationChallenge;
typedef mach_port_t io_object_t;
typedef char io_name_t[128];
typedef io_object_t io_iterator_t;
@@ -131,37 +172,32 @@ extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef
extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
-typedef struct CGColorSpace *CGColorSpaceRef;
+@interface NSTask : NSObject - (id)init;
+@end typedef struct CGColorSpace *CGColorSpaceRef;
typedef struct CGImage *CGImageRef;
- typedef struct CGLayer *CGLayerRef;
- @class NSArray, NSError, NSEvent, NSMenu, NSUndoManager, NSWindow;
+typedef struct CGLayer *CGLayerRef;
@interface NSResponder : NSObject <NSCoding> {
}
@end @protocol NSAnimatablePropertyContainer - (id)animator;
@end extern NSString *NSAnimationTriggerOrderIn ;
@interface NSView : NSResponder <NSAnimatablePropertyContainer> {
-struct __VFlags2 {
-}
-_vFlags2;
-}
-@end extern NSString * const NSFullScreenModeAllScreens;
-@protocol NSChangeSpelling - (void)changeSpelling:(id)sender;
-@end @protocol NSIgnoreMisspelledWords - (void)ignoreSpelling:(id)sender;
-@end @class NSColor, NSFont, NSNotification;
-@interface NSText : NSView <NSChangeSpelling, NSIgnoreMisspelledWords> {
}
@end @protocol NSValidatedUserInterfaceItem - (SEL)action;
@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
-@end @class NSArray, NSError, NSImage, NSView, NSNotificationCenter, NSURL, NSScreen, NSRunningApplication;
+@end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
@interface NSApplication : NSResponder <NSUserInterfaceValidations> {
}
@end enum {
NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 };
typedef NSUInteger NSApplicationTerminateReply;
@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
-@end enum {
+@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
+@interface NSCell : NSObject <NSCopying, NSCoding> {
}
-_CFlags;
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
@interface CIImage : NSObject <NSCoding, NSCopying> {
}
typedef int CIFormat;
@@ -175,7 +211,7 @@ extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn stat
- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
-@end @class NSURL;
+@end extern NSString* const QCRendererEventKey;
@protocol QCCompositionRenderer - (NSDictionary*) attributes;
@end @interface QCRenderer : NSObject <QCCompositionRenderer> {
}
@@ -188,11 +224,34 @@ extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn stat
ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, };
@class ICDevice;
@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device;
-@end @class ICCameraDevice;
+@end extern NSString *const ICScannerStatusWarmingUp;
@class ICScannerDevice;
@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
@end
-
+
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+typedef unsigned long CFTypeID;
+struct CGPoint {
+ CGFloat x;
+ CGFloat y;
+};
+typedef struct CGPoint CGPoint;
+typedef struct CGGradient *CGGradientRef;
+typedef uint32_t CGGradientDrawingOptions;
+extern CFTypeID CGGradientGetTypeID(void);
+extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef
+ space, const CGFloat components[], const CGFloat locations[], size_t count);
+extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
+ CFArrayRef colors, const CGFloat locations[]);
+extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
+extern void CGGradientRelease(CGGradientRef gradient);
+typedef struct CGContext *CGContextRef;
+extern void CGContextDrawLinearGradient(CGContextRef context,
+ CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
+ CGGradientDrawingOptions options);
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+
//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//
@@ -371,6 +430,7 @@ CFMutableArrayRef f13_autorelease_d() {
[(id) A autorelease];
CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}}
CFRelease(B); // no-warning
+ while (1) {}
}
@@ -389,6 +449,18 @@ void f15() {
CFRelease(*B); // no-warning
}
+// Test when we pass NULL to CFRetain/CFRelease.
+void f16(int x, CFTypeRef p) {
+ if (p)
+ return;
+
+ if (x) {
+ CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
+ }
+ else {
+ CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
+ }
+}
// Test basic tracking of ivars associated with 'self'. For the retain/release
// checker we currently do not want to flag leaks associated with stores
@@ -559,7 +631,7 @@ void rdar6704930(unsigned char *s, unsigned int length) {
int rdar_6257780_Case1() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *array = [NSArray array];
- [array release]; // expected-warning{{Incorrect decrement of the reference count of an object is not owned at this point by the caller}}
+ [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
[pool drain];
return 0;
}
@@ -603,7 +675,8 @@ typedef CFTypeRef OtherRef;
@end
//===----------------------------------------------------------------------===//
-//<rdar://problem/6320065> false positive - init method returns an object owned by caller
+//<rdar://problem/6320065> false positive - init method returns an object
+// owned by caller
//===----------------------------------------------------------------------===//
@interface RDar6320065 : NSObject {
@@ -646,7 +719,21 @@ int RDar6320065_test() {
}
//===----------------------------------------------------------------------===//
-// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a retained object
+// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object
+// and claims the receiver
+//===----------------------------------------------------------------------===//
+
+@interface RDar7129086 : NSObject {} @end
+@implementation RDar7129086
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder {
+ [self release]; // no-warning
+ return [NSString alloc]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a
+// retained object
//===----------------------------------------------------------------------===//
@interface RDar6859457 : NSObject {}
@@ -750,7 +837,7 @@ void IOServiceNameMatching_wrapper(const char * name) {
IOServiceNameMatching(name); // expected-warning{{leak}}
}
-__attribute__((cf_returns_retained)) CFDictionaryRef CreateDict();
+CF_RETURNS_RETAINED CFDictionaryRef CreateDict();
void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
@@ -791,19 +878,241 @@ void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort,
}
//===----------------------------------------------------------------------===//
+// Test of handling objects whose references "escape" to containers.
+//===----------------------------------------------------------------------===//
+
+// <rdar://problem/6539791>
+void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) {
+ CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(y, key, x);
+ CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
+ if (value) {
+ CFDictionaryAddValue(x, val_key, value); // no-warning
+ CFRelease(value);
+ CFDictionaryAddValue(y, val_key, value); // no-warning
+ }
+}
+
+// <rdar://problem/6560661>
+// Same issue, except with "AppendValue" functions.
+void rdar_6560661(CFMutableArrayRef x) {
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
+ // CFArrayAppendValue keeps a reference to value.
+ CFArrayAppendValue(x, value);
+ CFRelease(value);
+ CFRetain(value);
+ CFRelease(value); // no-warning
+}
+
+// <rdar://problem/7152619>
+// Same issue, excwept with "CFAttributeStringSetAttribute".
+void rdar_7152619(CFStringRef str) {
+ CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0);
+ CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string);
+ CFRelease(string);
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+ CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number);
+ [number release];
+ [number retain];
+ CFRelease(attrString);
+}
+
+//===----------------------------------------------------------------------===//
+// Test of handling CGGradientXXX functions.
+//===----------------------------------------------------------------------===//
+
+void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint,
+ CGPoint myEndPoint) {
+ size_t num_locations = 6;
+ CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 };
+ CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0,
+ x, // Start color
+ 207.0/255.0, 39.0/255.0, 39.0/255.0, x,
+ 147.0/255.0, 21.0/255.0, 22.0/255.0, x,
+ 175.0/255.0, 175.0/255.0, 175.0/255.0, x,
+ 255.0/255.0,255.0/255.0, 255.0/255.0, x,
+ 255.0/255.0,255.0/255.0, 255.0/255.0, x
+ }; // End color
+
+ CGGradientRef myGradient =
+ CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}}
+ components, locations, num_locations);
+
+ CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint,
+ 0);
+ CGGradientRelease(myGradient);
+}
+
+void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint,
+ CGPoint myEndPoint) {
+ size_t num_locations = 6;
+ CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 };
+ CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0,
+ x, // Start color
+ 207.0/255.0, 39.0/255.0, 39.0/255.0, x,
+ 147.0/255.0, 21.0/255.0, 22.0/255.0, x,
+ 175.0/255.0, 175.0/255.0, 175.0/255.0, x,
+ 255.0/255.0,255.0/255.0, 255.0/255.0, x,
+ 255.0/255.0,255.0/255.0, 255.0/255.0, x
+ }; // End color
+
+ CGGradientRef myGradient =
+ CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}}
+
+ CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint,
+ 0);
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7299394> clang false positive: retained instance passed to
+// thread in pthread_create marked as leak
+//
+// Until we have full IPA, the analyzer should stop tracking the reference
+// count of objects passed to pthread_create.
+//
+//===----------------------------------------------------------------------===//
+
+struct _opaque_pthread_t {};
+struct _opaque_pthread_attr_t {};
+typedef struct _opaque_pthread_t *__darwin_pthread_t;
+typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
+typedef __darwin_pthread_t pthread_t;
+typedef __darwin_pthread_attr_t pthread_attr_t;
+
+int pthread_create(pthread_t * restrict, const pthread_attr_t * restrict,
+ void *(*)(void *), void * restrict);
+
+void *rdar_7299394_start_routine(void *p) {
+ [((id) p) release];
+ return 0;
+}
+void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) {
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+ pthread_create(thread, attr, rdar_7299394_start_routine, number);
+}
+void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) {
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7283567> False leak associated with call to
+// CVPixelBufferCreateWithBytes ()
+//
+// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and
+// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the
+// pixel buffer object. These test cases show how the analyzer stops tracking
+// the reference count for the objects passed for this argument. This
+// could be made smarter.
+//===----------------------------------------------------------------------===//
+
+typedef int int32_t;
+typedef UInt32 FourCharCode;
+typedef FourCharCode OSType;
+typedef uint64_t CVOptionFlags;
+typedef int32_t CVReturn;
+typedef struct __CVBuffer *CVBufferRef;
+typedef CVBufferRef CVImageBufferRef;
+typedef CVImageBufferRef CVPixelBufferRef;
+typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress );
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] );
+
+extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *dataPtr,
+ size_t dataSize,
+ size_t numberOfPlanes,
+ void *planeBaseAddress[],
+ size_t planeWidth[],
+ size_t planeHeight[],
+ size_t planeBytesPerRow[],
+ CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height,
+ OSType pixelFormatType, void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) {
+
+ // For the allocated object, it doesn't really matter what type it is
+ // for the purpose of this test. All we want to show is that
+ // this is freed later by the callback.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+ return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType,
+ baseAddress, bytesPerRow, releaseCallback,
+ number, // potentially released by callback
+ pixelBufferAttributes, pixelBufferOut) ;
+}
+
+CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height,
+ OSType pixelFormatType, void *dataPtr, size_t dataSize,
+ size_t numberOfPlanes, void *planeBaseAddress[],
+ size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[],
+ CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) {
+
+ // For the allocated object, it doesn't really matter what type it is
+ // for the purpose of this test. All we want to show is that
+ // this is freed later by the callback.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+ return CVPixelBufferCreateWithPlanarBytes(allocator,
+ width, height, pixelFormatType, dataPtr, dataSize,
+ numberOfPlanes, planeBaseAddress, planeWidth,
+ planeHeight, planeBytesPerRow, releaseCallback,
+ number, // potentially released by callback
+ pixelBufferAttributes, pixelBufferOut) ;
+}
+
+//===----------------------------------------------------------------------===//
// Tests of ownership attributes.
//===----------------------------------------------------------------------===//
typedef NSString* MyStringTy;
+@protocol FooP;
+
@interface TestOwnershipAttr : NSObject
-- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained)); // no-warning
-- (NSString*) returnsAnOwnedCFString __attribute__((cf_returns_retained)); // no-warning
-- (MyStringTy) returnsAnOwnedTypedString __attribute__((ns_returns_retained)); // no-warning
-- (int) returnsAnOwnedInt __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
+- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning
+- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning
+- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
+- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
@end
-static int ownership_attribute_doesnt_go_here __attribute__((ns_returns_retained)); // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}}
+static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to function or method types}}
void test_attr_1(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
@@ -814,12 +1123,14 @@ void test_attr_1b(TestOwnershipAttr *X) {
}
@interface MyClassTestCFAttr : NSObject {}
-- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
+- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;
+- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED;
- (NSDate*) alsoReturnsRetained;
-- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
+- (CFDateRef) alsoReturnsRetainedAsCF;
+- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED;
@end
-__attribute__((cf_returns_retained))
+CF_RETURNS_RETAINED
CFDateRef returnsRetainedCFDate() {
return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
}
@@ -829,14 +1140,58 @@ CFDateRef returnsRetainedCFDate() {
return (NSDate*) returnsRetainedCFDate(); // No leak.
}
+- (CFDateRef) returnsCFRetainedAsCF {
+ return returnsRetainedCFDate(); // No leak.
+}
+
+
- (NSDate*) alsoReturnsRetained {
return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
}
+- (CFDateRef) alsoReturnsRetainedAsCF {
+ return returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+
+
- (NSDate*) returnsNSRetained {
return (NSDate*) returnsRetainedCFDate(); // no-warning
}
@end
+//===----------------------------------------------------------------------===//
+// Test that leaks post-dominated by "panic" functions are not reported.
+//
+// <rdar://problem/5905851> do not report a leak when post-dominated by a call
+// to a noreturn or panic function
+//===----------------------------------------------------------------------===//
+
+void panic() __attribute__((noreturn));
+
+void test_panic_negative() {
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}}
+}
+
+void test_panic_positive() {
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning
+ panic();
+}
+void test_panic_neg_2(int x) {
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}}
+ if (x)
+ panic();
+}
+
+void test_panic_pos_2(int x) {
+ signed z = 1;
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning
+ if (x)
+ panic();
+ if (!x)
+ panic();
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
new file mode 100644
index 000000000000..ebd7d172b5b4
--- /dev/null
+++ b/test/Analysis/security-syntax-checks.m
@@ -0,0 +1,91 @@
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -warn-security-syntactic %s -verify
+
+// <rdar://problem/6336718> rule request: floating point used as loop
+// condition (FLP30-C, FLP-30-CPP)
+//
+// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
+//
+void test_float_condition() {
+ for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+ for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+ for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
+ for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+ for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+
+ for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+
+ int i = 0;
+ for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
+
+ typedef float FooType;
+ for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
+}
+
+// <rdar://problem/6335715> rule request: gets() buffer overflow
+// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
+char* gets(char *buf);
+
+void test_gets() {
+ char buff[1024];
+ gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
+}
+
+// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
+// Dropped Successfully
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_uid_t;
+typedef __uint32_t __darwin_gid_t;
+typedef __darwin_uid_t uid_t;
+typedef __darwin_gid_t gid_t;
+int setuid(uid_t);
+int setregid(gid_t, gid_t);
+int setreuid(uid_t, uid_t);
+extern void check(int);
+
+void test_setuid()
+{
+ setuid(2); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+ setuid(0); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+ if (setuid (2) != 0)
+ abort();
+
+ // Currently the 'setuid' check is not flow-sensitive, and only looks
+ // at whether the function was called in a compound statement. This
+ // will lead to false negatives, but there should be no false positives.
+ int t = setuid(2); // no-warning
+ (void)setuid (2); // no-warning
+
+ check(setuid (2)); // no-warning
+
+ setreuid(2,2); // expected-warning{{The return value from the call to 'setreuid' is not checked. If an error occurs in 'setreuid', the following code may execute with unexpected privileges}}
+ setregid(2,2); // expected-warning{{The return value from the call to 'setregid' is not checked. If an error occurs in 'setregid', the following code may execute with unexpected privileges}}
+}
+
+// <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng
+int rand(void);
+double drand48(void);
+double erand48(unsigned short[3]);
+long jrand48(unsigned short[3]);
+void lcong48(unsigned short[7]);
+long lrand48(void);
+long mrand48(void);
+long nrand48(unsigned short[3]);
+long random(void);
+int rand_r(unsigned *);
+
+void test_rand()
+{
+ unsigned short a[7];
+ unsigned b;
+
+ rand(); // expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ drand48(); // expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ erand48(a); // expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ jrand48(a); // expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ lcong48(a); // expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ lrand48(); // expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ mrand48(); // expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ nrand48(a); // expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ rand_r(&b); // expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
+ random(); // expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict. Use 'arc4random' instead}}
+}
diff --git a/test/Analysis/uninit-vals-ps-region.c b/test/Analysis/uninit-vals-ps-region.c
index 32f787db4aeb..1561f11c9937 100644
--- a/test/Analysis/uninit-vals-ps-region.c
+++ b/test/Analysis/uninit-vals-ps-region.c
@@ -15,3 +15,21 @@ void f4() {
if (global.data == 0) // When the true branch is feasible 'a = 3'.
g(a); // no-warning
}
+
+
+// Test uninitialized value due to part of the structure being uninitialized.
+struct TestUninit { int x; int y; };
+struct TestUninit test_uninit_aux();
+void test_uninit_pos() {
+ struct TestUninit v1 = { 0, 0 };
+ struct TestUninit v2 = test_uninit_aux();
+ int z;
+ v1.y = z;
+ test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand of '+' is a garbage value}}
+}
+void test_uninit_neg() {
+ struct TestUninit v1 = { 0, 0 };
+ struct TestUninit v2 = test_uninit_aux();
+ test_unit_aux2(v2.x + v1.y); // no-warning
+}
+
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
index 41771265367a..759c7edbcc57 100644
--- a/test/Analysis/uninit-vals-ps.c
+++ b/test/Analysis/uninit-vals-ps.c
@@ -1,4 +1,4 @@
-// RUN: clang-cc -analyze -checker-cfref -verify %s &&
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
struct FPRec {
@@ -22,7 +22,7 @@ int f2() {
int x;
- if (x+1) // expected-warning{{Branch}}
+ if (x+1) // expected-warning{{The left operand of '+' is a garbage value}}
return 1;
return 2;
@@ -31,13 +31,13 @@ int f2() {
int f2_b() {
int x;
- return ((x+1)+2+((x))) + 1 ? 1 : 2; // expected-warning{{Branch}}
+ return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of '+' is a garbage value}}
}
int f3(void) {
int i;
int *p = &i;
- if (*p > 0) // expected-warning{{Branch condition evaluates to an uninitialized value}}
+ if (*p > 0) // expected-warning{{The left operand of '>' is a garbage value}}
return 0;
else
return 1;
@@ -61,7 +61,7 @@ int f5(void) {
int ret_uninit() {
int i;
int *p = &i;
- return *p; // expected-warning{{Uninitialized or undefined value returned to caller.}}
+ return *p; // expected-warning{{Undefined or garbage value returned to caller}}
}
// <rdar://problem/6451816>
@@ -83,3 +83,43 @@ CFStringRef rdar_6451816(CFNumberRef nr) {
return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning
}
+// PR 4630 - false warning with nonnull attribute
+// This false positive (due to a regression) caused the analyzer to falsely
+// flag a "return of uninitialized value" warning in the first branch due to
+// the nonnull attribute.
+void pr_4630_aux(char *x, int *y) __attribute__ ((nonnull (1)));
+void pr_4630_aux_2(char *x, int *y);
+int pr_4630(char *a, int y) {
+ int x;
+ if (y) {
+ pr_4630_aux(a, &x);
+ return x; // no-warning
+ }
+ else {
+ pr_4630_aux_2(a, &x);
+ return x; // no-warning
+ }
+}
+
+// PR 4631 - False positive with union initializer
+// Previously the analyzer didn't examine the compound initializers of unions,
+// resulting in some false positives for initializers with side-effects.
+union u_4631 { int a; };
+struct s_4631 { int a; };
+int pr4631_f2(int *p);
+int pr4631_f3(void *q);
+int pr4631_f1(void)
+{
+ int x;
+ union u_4631 m = { pr4631_f2(&x) };
+ pr4631_f3(&m); // tell analyzer that we use m
+ return x; // no-warning
+}
+int pr4631_f1_b(void)
+{
+ int x;
+ struct s_4631 m = { pr4631_f2(&x) };
+ pr4631_f3(&m); // tell analyzer that we use m
+ return x; // no-warning
+}
+
diff --git a/test/Analysis/uninit-vals.c b/test/Analysis/uninit-vals.c
index d69250b65c0b..8428ca4f81cd 100644
--- a/test/Analysis/uninit-vals.c
+++ b/test/Analysis/uninit-vals.c
@@ -23,7 +23,7 @@ int f4(int x) {
return y; // expected-warning {{use of uninitialized variable}}
}
-int f5() {
+void f5() {
int a;
a = 30; // no-warning
}
diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m
new file mode 100644
index 000000000000..be4f1852bf02
--- /dev/null
+++ b/test/Analysis/unions-region.m
@@ -0,0 +1,41 @@
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range %s -verify
+
+//===-- unions-region.m ---------------------------------------------------===//
+//
+// This file tests the analyzer's reasoning about unions.
+//
+//===----------------------------------------------------------------------===//
+
+// [testA] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testA_aux' and 'testA_aux_2'.
+union u_testA {
+ unsigned i;
+ float f;
+};
+
+float testA(float f) {
+ int testA_aux(unsigned x);
+ int testA_aux_2(union u_testA z);
+
+ union u_testA swap;
+ swap.f = f;
+
+ if (testA_aux(swap.i)) // no-warning
+ swap.i = ((swap.i & 0xffff0000) >> 16) | ((swap.i & 0x0000fffff) << 16);
+
+ testA_aux_2(swap); // no-warning
+
+ return swap.f;
+}
+
+// [testB] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testB_aux'.
+void testB(int i) {
+ void testB_aux(short z);
+ union { short x[2]; unsigned y; } val;
+ val.y = 10;
+ testB_aux(val.x[1]); // no-warning
+}
+
diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m
index 632b395c3e08..aacd44e7e677 100644
--- a/test/Analysis/unused-ivars.m
+++ b/test/Analysis/unused-ivars.m
@@ -1,10 +1,45 @@
-// RUN: clang-cc -analyze -warn-objc-unused-ivars %s -verify
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -warn-objc-unused-ivars %s -verify
-@interface A
-{
- @private int x; // expected-warning {{Instance variable 'x' in class 'A' is never used}}
+//===--- BEGIN: Delta-debugging reduced headers. --------------------------===//
+
+@protocol NSObject
+- (id)retain;
+- (oneway void)release;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+
+//===--- END: Delta-debugging reduced headers. ----------------------------===//
+
+// This test case tests the basic functionality of the unused ivar test.
+@interface TestA {
+@private
+ int x; // expected-warning {{Instance variable 'x' in class 'TestA' is never used}}
}
@end
+@implementation TestA @end
-@implementation A @end
+// This test case tests whether the unused ivar check handles blocks that
+// reference an instance variable. (<rdar://problem/7075531>)
+@interface TestB : NSObject {
+@private
+ id _ivar; // no-warning
+}
+@property (readwrite,retain) id ivar;
+@end
+
+@implementation TestB
+- (id)ivar {
+ __attribute__((__blocks__(byref))) id value = ((void*)0);
+ void (^b)() = ^{ value = _ivar; };
+ b();
+ return value;
+}
+- (void)setIvar:(id)newValue {
+ void (^b)() = ^{ [_ivar release]; _ivar = [newValue retain]; };
+ b();
+}
+@end