Check in LLVM r95781.
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m
new file mode 100644
index 0000000..abcefde
--- /dev/null
+++ b/test/Analysis/CFDateGC.m
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=basic %s -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -analyzer-constraints=range %s -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc -disable-free %s -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s -Wno-implicit-function-declaration
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h and CoreFoundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including [Core]Foundation.h directly makes this test case
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef const void * CFTypeRef;
+void CFRelease(CFTypeRef cf);
+CFTypeRef CFRetain(CFTypeRef cf);
+CFTypeRef CFMakeCollectable(CFTypeRef cf);
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+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) { return 0; }
+@protocol NSObject - (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (id)retain;
+@end
+@class NSArray;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent();
+
+CFAbsoluteTime f1_use_after_release() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ CFRetain(date);
+ [NSMakeCollectable(date) release];
+ CFDateGetAbsoluteTime(date); // no-warning
+ CFRelease(date);
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ return t;
+}
+
+// The following two test cases verifies that CFMakeCollectable is a no-op
+// in non-GC mode and a "release" in GC mode.
+CFAbsoluteTime f2_use_after_release() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ CFRetain(date);
+ [(id) CFMakeCollectable(date) release];
+ CFDateGetAbsoluteTime(date); // no-warning
+ CFRelease(date);
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ return t;
+}
+
+CFAbsoluteTime f2_noleak() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ CFRetain(date);
+ [(id) CFMakeCollectable(date) release];
+ CFDateGetAbsoluteTime(date); // no-warning
+ t = CFDateGetAbsoluteTime(date); // no-warning
+ CFRelease(date); // no-warning
+ return t;
+}
+
+void f3_leak_with_gc() {
+ CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning 2 {{leak}}
+ [[(id) date retain] release];
+}
+
+// The following test case verifies that we "stop tracking" a retained object
+// when it is passed as an argument to an implicitly defined function.
+CFAbsoluteTime f4() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ CFRetain(date);
+ some_implicitly_defined_function_stop_tracking(date); // no-warning
+ return t;
+}
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
new file mode 100644
index 0000000..544644a
--- /dev/null
+++ b/test/Analysis/CFNumber.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+
+typedef signed long CFIndex;
+typedef const struct __CFAllocator * CFAllocatorRef;
+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);
+
+CFNumberRef f1(unsigned char x) {
+ return CFNumberCreate(0, kCFNumberSInt16Type, &x); // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage.}}
+}
+
+CFNumberRef f2(unsigned short x) {
+ return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost.}}
+}
+
+CFNumberRef f3(unsigned i) {
+ return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer.}}
+}
diff --git a/test/Analysis/CFRetainRelease_NSAssertionHandler.m b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
new file mode 100644
index 0000000..ce9e6ff
--- /dev/null
+++ b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=basic
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=basic
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=region
+
+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
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} - (id)init; @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 NSAssertionHandler : NSObject {}
++ (NSAssertionHandler *)currentHandler;
+- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+
+//----------------------------------------------------------------------------//
+// The following test case was filed in PR 2593:
+// http://llvm.org/bugs/show_bug.cgi?id=2593
+//
+// There should be no null dereference flagged by the checker because of
+// NSParameterAssert and NSAssert.
+
+
+@interface TestAssert : NSObject {}
+@end
+
+@implementation TestAssert
+
+- (id)initWithPointer: (int*)x
+{
+ // Expansion of: NSParameterAssert( x != 0 );
+ do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:21 description:(@"Invalid parameter not satisfying: %s"), ("x != 0"), (0), (0), (0), (0)]; } } while(0);
+
+ if( (self = [super init]) != 0 )
+ {
+ *x = 1; // no-warning
+ }
+
+ return self;
+}
+
+- (id)initWithPointer2: (int*)x
+{
+ // Expansion of: NSAssert( x != 0, @"" );
+ do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:33 description:((@"")), (0), (0), (0), (0), (0)]; } } while(0);
+
+ if( (self = [super init]) != 0 )
+ {
+ *x = 1; // no-warning
+ }
+
+ return self;
+}
+
+@end
diff --git a/test/Analysis/CGColorSpace.c b/test/Analysis/CGColorSpace.c
new file mode 100644
index 0000000..737f1a3
--- /dev/null
+++ b/test/Analysis/CGColorSpace.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+extern CGColorSpaceRef CGColorSpaceRetain(CGColorSpaceRef space);
+extern void CGColorSpaceRelease(CGColorSpaceRef space);
+
+void f() {
+ CGColorSpaceRef X = CGColorSpaceCreateDeviceRGB(); // expected-warning{{leak}}
+ CGColorSpaceRetain(X);
+}
+
+void fb() {
+ CGColorSpaceRef X = CGColorSpaceCreateDeviceRGB();
+ CGColorSpaceRetain(X);
+ CGColorSpaceRelease(X);
+ CGColorSpaceRelease(X); // no-warning
+}
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
new file mode 100644
index 0000000..6bf299d
--- /dev/null
+++ b/test/Analysis/CheckNSError.m
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+@class NSDictionary;
+@interface NSError : NSObject <NSCopying, NSCoding> {}
++ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict;
+@end
+extern NSString * const NSXMLParserErrorDomain ;
+
+@interface A
+- (void)myMethodWhichMayFail:(NSError **)error;
+- (BOOL)myMethodWhichMayFail2:(NSError **)error;
+@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 occurred}}
+ *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
+}
+
+- (BOOL)myMethodWhichMayFail2:(NSError **)error { // no-warning
+ if (error) *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // no-warning
+ return 0;
+}
+@end
+
+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 occurred}}
+ *error = 0; // expected-warning {{Potential null dereference.}}
+}
+
+int f1(CFErrorRef* error) {
+ if (error) *error = 0; // no-warning
+ return 0;
+}
+
+int f2(CFErrorRef* error) {
+ if (0 != error) *error = 0; // no-warning
+ return 0;
+}
+
+int f3(CFErrorRef* error) {
+ if (error != 0) *error = 0; // no-warning
+ return 0;
+}
+
+
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m
new file mode 100644
index 0000000..bfd968a
--- /dev/null
+++ b/test/Analysis/MissingDealloc.m
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s -verify
+typedef signed char BOOL;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (Class)class;
+@end
+
+@interface NSObject <NSObject> {}
+- (void)dealloc;
+- (id)init;
+@end
+
+typedef struct objc_selector *SEL;
+
+// <rdar://problem/6380411>: 'myproperty' has kind 'assign' and thus the
+// assignment through the setter does not perform a release.
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty=_myproperty; // no-warning
+- (void)dealloc {
+ self.myproperty = 0;
+ [super dealloc];
+}
+@end
+
+//===------------------------------------------------------------------------===
+// Don't warn about iVars that are selectors.
+
+@interface TestSELs : NSObject {
+ SEL a;
+ SEL b;
+}
+
+@end
+
+@implementation TestSELs
+- (id)init {
+ if( (self = [super init]) ) {
+ a = @selector(a);
+ b = @selector(b);
+ }
+
+ return self;
+}
+@end
+
+//===------------------------------------------------------------------------===
+// Don't warn about iVars that are IBOutlets.
+
+#ifndef IBOutlet
+#define IBOutlet
+#endif
+
+@class NSWindow;
+
+@interface HasOutlet : NSObject {
+IBOutlet NSWindow *window;
+}
+@end
+
+@implementation HasOutlet // no-warning
+@end
+
+//===------------------------------------------------------------------------===
+// <rdar://problem/6380411>
+// Was bogus warning: "The '_myproperty' instance variable was not retained by a
+// synthesized property but was released in 'dealloc'"
+
+@interface MyObject_rdar6380411 : NSObject {
+ id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject_rdar6380411
+@synthesize myproperty=_myproperty;
+- (void)dealloc {
+ // Don't claim that myproperty is released since it the property
+ // has the 'assign' attribute.
+ self.myproperty = 0; // no-warning
+ [super dealloc];
+}
+@end
+
+//===------------------------------------------------------------------------===
+// PR 3187: http://llvm.org/bugs/show_bug.cgi?id=3187
+// - Disable the missing -dealloc check for classes that subclass SenTestCase
+
+@class NSString;
+
+@interface SenTestCase : NSObject {}
+@end
+
+@interface MyClassTest : SenTestCase {
+ NSString *resourcePath;
+}
+@end
+
+@interface NSBundle : NSObject {}
++ (NSBundle *)bundleForClass:(Class)aClass;
+- (NSString *)resourcePath;
+@end
+
+@implementation MyClassTest
+- (void)setUp {
+ resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
+}
+- (void)testXXX {
+ // do something which uses resourcepath
+}
+@end
diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m
new file mode 100644
index 0000000..7ebe18f
--- /dev/null
+++ b/test/Analysis/NSPanel.m
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// BEGIN delta-debugging reduced header stuff
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@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)alloc;
+@end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRect;
+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;
+@end
+@class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+@end @class NSAppleEventDescriptor;
+enum { NSBackingStoreRetained = 0, NSBackingStoreNonretained = 1, NSBackingStoreBuffered = 2 };
+typedef NSUInteger NSBackingStoreType;
+@interface NSResponder : NSObject <NSCoding> {} @end
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+@protocol NSValidatedUserInterfaceItem
+- (SEL)action;
+@end
+@protocol NSUserInterfaceValidations
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+@end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };
+@interface NSWindow : NSResponder <NSAnimatablePropertyContainer, NSUserInterfaceValidations> {}
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
+@end
+extern NSString *NSWindowDidBecomeKeyNotification;
+@interface NSPanel : NSWindow {}
+@end
+@class NSTableHeaderView;
+
+// END delta-debugging reduced header stuff
+
+@interface MyClass
+{
+ NSMutableArray *panels;
+}
+- (void)myMethod;
+- (void)myMethod2;
+@end
+
+@implementation MyClass // no-warning
+- (void)myMethod
+{
+ NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1];
+
+ [panels addObject:panel];
+
+ [panel release]; // no-warning
+}
+- (void)myMethod2
+{
+ NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1]; // no-warning
+
+ [panels addObject:panel];
+}
+@end
+
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
new file mode 100644
index 0000000..fa81b3d
--- /dev/null
+++ b/test/Analysis/NSString.m
@@ -0,0 +1,406 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// ==-- FIXME: -analyzer-store=basic fails on this file (false negatives). --==
+// NOTWORK: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s &&
+// NOTWORK: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
+// NOTWORK: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
+// NOTWORK: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+#ifdef TEST_64
+typedef long long int64_t;
+_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap64Barrier
+typedef int64_t intptr_t;
+#else
+typedef int int32_t;
+_Bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
+#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap32Barrier
+typedef int32_t intptr_t;
+#endif
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+void CFRelease(CFTypeRef cf);
+typedef const struct __CFDictionary * CFDictionaryRef;
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef NSInteger NSComparisonResult;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (id)retain;
+- (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;
++ (id)alloc;
+@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;
+typedef struct _NSRange {} NSRange;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+- (id)initWithCapacity:(NSUInteger)numItems;
+@end
+typedef unsigned short unichar;
+@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
+typedef NSUInteger NSStringCompareOptions;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+- (NSComparisonResult)compare:(NSString *)string;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
+- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
+- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
++ (id)stringWithFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+NSComparisonResult f1(NSString* s) {
+ NSString *aString = 0;
+ return [s compare:aString]; // expected-warning {{Argument to 'NSString' method 'compare:' cannot be nil.}}
+}
+
+NSComparisonResult f2(NSString* s) {
+ NSString *aString = 0;
+ return [s caseInsensitiveCompare:aString]; // expected-warning {{Argument to 'NSString' method 'caseInsensitiveCompare:' cannot be nil.}}
+}
+
+NSComparisonResult f3(NSString* s, NSStringCompareOptions op) {
+ NSString *aString = 0;
+ return [s compare:aString options:op]; // expected-warning {{Argument to 'NSString' method 'compare:options:' cannot be nil.}}
+}
+
+NSComparisonResult f4(NSString* s, NSStringCompareOptions op, NSRange R) {
+ NSString *aString = 0;
+ return [s compare:aString options:op range:R]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:' cannot be nil.}}
+}
+
+NSComparisonResult f5(NSString* s, NSStringCompareOptions op, NSRange R) {
+ NSString *aString = 0;
+ return [s compare:aString options:op range:R locale:0]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:locale:' cannot be nil.}}
+}
+
+NSArray *f6(NSString* s) {
+ return [s componentsSeparatedByCharactersInSet:0]; // expected-warning {{Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil.}}
+}
+
+NSString* f7(NSString* s1, NSString* s2, NSString* s3) {
+
+ NSString* s4 = (NSString*)
+ CFStringCreateWithFormat(kCFAllocatorDefault, 0, // expected-warning{{leak}}
+ (CFStringRef) __builtin___CFStringMakeConstantString("%@ %@ (%@)"),
+ s1, s2, s3);
+
+ CFRetain(s4);
+ return s4;
+}
+
+NSMutableArray* f8() {
+
+ NSString* s = [[NSString alloc] init];
+ NSMutableArray* a = [[NSMutableArray alloc] initWithCapacity:2];
+ [a addObject:s];
+ [s release]; // no-warning
+ return a;
+}
+
+void f9() {
+
+ NSString* s = [[NSString alloc] init];
+ NSString* q = s;
+ [s release];
+ [q release]; // expected-warning {{used after it is released}}
+}
+
+NSString* f10() {
+ static NSString* s = 0;
+ if (!s) s = [[NSString alloc] init];
+ return s; // no-warning
+}
+
+// Test case for regression reported in <rdar://problem/6452745>.
+// Essentially 's' should not be considered allocated on the false branch.
+// This exercises the 'EvalAssume' logic in GRTransferFuncs (CFRefCount.cpp).
+NSString* f11(CFDictionaryRef dict, const char* key) {
+ NSString* s = (NSString*) CFDictionaryGetValue(dict, key);
+ [s retain];
+ if (s) {
+ [s release];
+ }
+ return 0;
+}
+
+// Test case for passing a tracked object by-reference to a function we
+// don't understand.
+void unknown_function_f12(NSString** s);
+void f12() {
+ NSString *string = [[NSString alloc] init];
+ unknown_function_f12(&string); // no-warning
+}
+
+// Test double release of CFString (PR 4014).
+void f13(void) {
+ CFStringRef ref = CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100);
+ CFRelease(ref);
+ CFRelease(ref); // expected-warning{{Reference-counted object is used after it is released}}
+}
+
+// Test regular use of -autorelease
+@interface TestAutorelease
+-(NSString*) getString;
+@end
+@implementation TestAutorelease
+-(NSString*) getString {
+ NSString *str = [[NSString alloc] init];
+ return [str autorelease]; // no-warning
+}
+- (void)m1
+{
+ NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+ [s retain];
+ [s autorelease];
+}
+- (void)m2
+{
+ NSString *s = [[[NSString alloc] init] autorelease]; // expected-warning{{leak}}
+ [s retain];
+}
+- (void)m3
+{
+ NSString *s = [[[NSString alloc] init] autorelease];
+ [s retain];
+ [s autorelease];
+}
+- (void)m4
+{
+ NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+ [s retain];
+}
+- (void)m5
+{
+ NSString *s = [[NSString alloc] init];
+ [s autorelease];
+}
+@end
+
+@interface C1 : NSObject {}
+- (NSString*) getShared;
++ (C1*) sharedInstance;
+@end
+@implementation C1 : NSObject {}
+- (NSString*) getShared {
+ static NSString* s = 0;
+ if (!s) s = [[NSString alloc] init];
+ return s; // no-warning
+}
++ (C1 *)sharedInstance {
+ static C1 *sharedInstance = 0;
+ if (!sharedInstance) {
+ sharedInstance = [[C1 alloc] init];
+ }
+ return sharedInstance; // no-warning
+}
+@end
+
+@interface SharedClass : NSObject
++ (id)sharedInstance;
+- (id)notShared;
+@end
+
+@implementation SharedClass
+
+- (id)_init {
+ if ((self = [super init])) {
+ NSLog(@"Bar");
+ }
+ return self;
+}
+
+- (id)notShared {
+ return [[SharedClass alloc] _init]; // expected-warning{{leak}}
+}
+
++ (id)sharedInstance {
+ static SharedClass *_sharedInstance = 0;
+ if (!_sharedInstance) {
+ _sharedInstance = [[SharedClass alloc] _init];
+ }
+ return _sharedInstance; // no-warning
+}
+@end
+
+id testSharedClassFromFunction() {
+ return [[SharedClass alloc] _init]; // no-warning
+}
+
+// Test OSCompareAndSwap
+_Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue );
+extern BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation);
+
+void testOSCompareAndSwap() {
+ NSString *old = 0;
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!OSAtomicCompareAndSwapPtr(0, s, (void**) &old))
+ [s release];
+ else
+ [old release];
+}
+
+void testOSCompareAndSwapXXBarrier_local() {
+ NSString *old = 0;
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) &old))
+ [s release];
+ else
+ [old release];
+}
+
+void testOSCompareAndSwapXXBarrier_local_no_direct_release() {
+ NSString *old = 0;
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) &old))
+ return;
+ else
+ [old release];
+}
+
+int testOSCompareAndSwapXXBarrier_id(Class myclass, id xclass) {
+ if (COMPARE_SWAP_BARRIER(0, (intptr_t) myclass, (intptr_t*) &xclass))
+ return 1;
+ return 0;
+}
+
+void test_objc_atomicCompareAndSwap_local() {
+ NSString *old = 0;
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!objc_atomicCompareAndSwapPtr(0, s, &old))
+ [s release];
+ else
+ [old release];
+}
+
+void test_objc_atomicCompareAndSwap_local_no_direct_release() {
+ NSString *old = 0;
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!objc_atomicCompareAndSwapPtr(0, s, &old))
+ return;
+ else
+ [old release];
+}
+
+void test_objc_atomicCompareAndSwap_parameter(NSString **old) {
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!objc_atomicCompareAndSwapPtr(0, s, old))
+ [s release];
+ else
+ [*old release];
+}
+
+void test_objc_atomicCompareAndSwap_parameter_no_direct_release(NSString **old) {
+ NSString *s = [[NSString alloc] init]; // expected-warning{{leak}}
+ if (!objc_atomicCompareAndSwapPtr(0, s, old))
+ return;
+ else
+ [*old release];
+}
+
+
+// Test stringWithFormat (<rdar://problem/6815234>)
+void test_stringWithFormat() {
+ NSString *string = [[NSString stringWithFormat:@"%ld", (long) 100] retain];
+ [string release];
+ [string release]; // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// Test isTrackedObjectType().
+typedef NSString* WonkyTypedef;
+@interface TestIsTracked
++ (WonkyTypedef)newString;
+@end
+
+void test_isTrackedObjectType(void) {
+ NSString *str = [TestIsTracked newString]; // expected-warning{{Potential leak}}
+}
+
+// Test isTrackedCFObjectType().
+@interface TestIsCFTracked
++ (CFStringRef) badNewCFString;
++ (CFStringRef) newCFString;
+@end
+
+@implementation TestIsCFTracked
++ (CFStringRef) newCFString {
+ return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // no-warning
+}
++ (CFStringRef) badNewCFString {
+ return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // expected-warning{{leak}}
+}
+
+// Test @synchronized
+void test_synchronized(id x) {
+ @synchronized(x) {
+ NSString *string = [[NSString stringWithFormat:@"%ld", (long) 100] retain]; // expected-warning {{leak}}
+ }
+}
+@end
+
+void testOSCompareAndSwapXXBarrier_parameter(NSString **old) {
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old))
+ [s release];
+ else
+ [*old release];
+}
+
+void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) {
+ NSString *s = [[NSString alloc] init]; // no-warning
+ if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old))
+ [s release];
+ else
+ return;
+}
diff --git a/test/Analysis/NSWindow.m b/test/Analysis/NSWindow.m
new file mode 100644
index 0000000..34e6c68
--- /dev/null
+++ b/test/Analysis/NSWindow.m
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// These declarations were reduced using Delta-Debugging from Foundation.h
+// on Mac OS X. The test cases are below.
+
+typedef struct objc_selector *SEL;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+@end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+ + (id)alloc;
+@end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRect;
+NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h);
+enum { NSBackingStoreRetained = 0, NSBackingStoreNonretained = 1, NSBackingStoreBuffered = 2 };
+typedef NSUInteger NSBackingStoreType;
+@interface NSResponder : NSObject <NSCoding> {}
+@end
+@protocol NSAnimatablePropertyContainer
+- (id)animator;
+@end
+extern NSString *NSAnimationTriggerOrderIn ;
+@class CIFilter, CALayer, NSDictionary, NSScreen, NSShadow, NSTrackingArea;
+@interface NSView : NSResponder <NSAnimatablePropertyContainer> {} @end
+@protocol NSValidatedUserInterfaceItem - (SEL)action; @end
+@protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; @end @class NSNotification, NSText, NSView, NSMutableSet, NSSet, NSDate;
+enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };
+@interface NSWindow : NSResponder <NSAnimatablePropertyContainer, NSUserInterfaceValidations> {
+ struct __wFlags {} _wFlags;
+}
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen;
+- (void)orderFrontRegardless;
+@end
+
+extern NSString *NSWindowDidBecomeKeyNotification;
+
+// Test cases.
+
+void f1() {
+ NSWindow *window = [[NSWindow alloc]
+ initWithContentRect:NSMakeRect(0,0,100,100)
+ styleMask:NSTitledWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered
+ defer:0];
+
+ [window orderFrontRegardless]; // no-warning
+}
+
+void f2() {
+ NSWindow *window = [[NSWindow alloc]
+ initWithContentRect:NSMakeRect(0,0,100,100)
+ styleMask:NSTitledWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered
+ defer:0
+ screen:0];
+
+ [window orderFrontRegardless]; // no-warning
+}
+
+void f2b() {
+ // FIXME: NSWindow doesn't own itself until it is displayed.
+ NSWindow *window = [[NSWindow alloc] // no-warning
+ initWithContentRect:NSMakeRect(0,0,100,100)
+ styleMask:NSTitledWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered
+ defer:0
+ screen:0];
+
+ [window orderFrontRegardless];
+
+ [window retain];
+}
+
+
+void f3() {
+ // FIXME: For now we don't track NSWindow.
+ NSWindow *window = [NSWindow alloc]; // expected-warning{{never read}}
+}
diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m
new file mode 100644
index 0000000..a02c93c
--- /dev/null
+++ b/test/Analysis/NoReturn.m
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+#include <stdarg.h>
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
++ (id)stringWithFormat:(NSString *)format, ...;
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
+@class NSString, NSDictionary, NSArray;
+@interface NSException : NSObject <NSCopying, NSCoding> {}
++ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
+- (void)raise;
+@end
+@interface NSException (NSExceptionRaisingConveniences)
++ (void)raise:(NSString *)name format:(NSString *)format, ...;
++ (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
+@end
+
+enum {NSPointerFunctionsStrongMemory = (0 << 0), NSPointerFunctionsZeroingWeakMemory = (1 << 0), NSPointerFunctionsOpaqueMemory = (2 << 0), NSPointerFunctionsMallocMemory = (3 << 0), NSPointerFunctionsMachVirtualMemory = (4 << 0), NSPointerFunctionsObjectPersonality = (0 << 8), NSPointerFunctionsOpaquePersonality = (1 << 8), NSPointerFunctionsObjectPointerPersonality = (2 << 8), NSPointerFunctionsCStringPersonality = (3 << 8), NSPointerFunctionsStructPersonality = (4 << 8), NSPointerFunctionsIntegerPersonality = (5 << 8), NSPointerFunctionsCopyIn = (1 << 16), };
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+int f1(int *x, NSString* s) {
+
+ if (x) ++x;
+
+ [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
+
+ return *x; // no-warning
+}
+
+int f2(int *x, ...) {
+
+ if (x) ++x;
+ va_list alist;
+ va_start(alist, x);
+
+ [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
+
+ return *x; // no-warning
+}
+
+int f3(int* x) {
+
+ if (x) ++x;
+
+ [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];
+
+ return *x; // no-warning
+}
+
diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m
new file mode 100644
index 0000000..72f3d38
--- /dev/null
+++ b/test/Analysis/ObjCProperties.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range %s -verify
+
+// The point of this test cases is to exercise properties in the static
+// analyzer
+
+@interface MyClass {
+@private
+ id _X;
+}
+- (id)initWithY:(id)Y;
+@property(copy, readwrite) id X;
+@end
+
+@implementation MyClass
+@synthesize X = _X;
+- (id)initWithY:(id)Y {
+ self.X = Y;
+ return self;
+}
+@end
diff --git a/test/Analysis/ObjCRetSigs.m b/test/Analysis/ObjCRetSigs.m
new file mode 100644
index 0000000..a76d7b9
--- /dev/null
+++ b/test/Analysis/ObjCRetSigs.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-methodsigs -verify %s
+
+int printf(const char *, ...);
+
+@interface MyBase
+-(long long)length;
+@end
+
+@interface MySub : MyBase{}
+-(double)length;
+@end
+
+@implementation MyBase
+-(long long)length{
+ printf("Called MyBase -length;\n");
+ return 3;
+}
+@end
+
+@implementation MySub
+-(double)length{ // expected-warning{{types are incompatible}}
+ printf("Called MySub -length;\n");
+ return 3.3;
+}
+@end
diff --git a/test/Analysis/PR2599.m b/test/Analysis/PR2599.m
new file mode 100644
index 0000000..68c8c06
--- /dev/null
+++ b/test/Analysis/PR2599.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=basic -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=range -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=basic -analyzer-store=basic -analyzer-check-objc-mem -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-constraints=range -analyzer-store=region -analyzer-check-objc-mem -fobjc-gc -verify %s
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFDictionary * CFDictionaryRef;
+CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, 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;
++ (id)alloc;
+@end
+enum { NSASCIIStringEncoding = 1, NSNEXTSTEPStringEncoding = 2, NSJapaneseEUCStringEncoding = 3, NSUTF8StringEncoding = 4, NSISOLatin1StringEncoding = 5, NSSymbolStringEncoding = 6, NSNonLossyASCIIStringEncoding = 7, NSShiftJISStringEncoding = 8, NSISOLatin2StringEncoding = 9, NSUnicodeStringEncoding = 10, NSWindowsCP1251StringEncoding = 11, NSWindowsCP1252StringEncoding = 12, NSWindowsCP1253StringEncoding = 13, NSWindowsCP1254StringEncoding = 14, NSWindowsCP1250StringEncoding = 15, NSISO2022JPStringEncoding = 21, NSMacOSRomanStringEncoding = 30, NSUTF16StringEncoding = NSUnicodeStringEncoding, NSUTF16BigEndianStringEncoding = 0x90000100, NSUTF16LittleEndianStringEncoding = 0x94000100, NSUTF32StringEncoding = 0x8c000100, NSUTF32BigEndianStringEncoding = 0x98000100, NSUTF32LittleEndianStringEncoding = 0x9c000100 };
+typedef NSUInteger NSStringEncoding;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)freeBuffer;
+@end
+@interface NSAutoreleasePool : NSObject {}
+- (void)drain;
+@end
+extern NSString * const NSXMLParserErrorDomain ;
+
+// The actual test case. UTIL_AUTORELEASE_CF_AS_ID is a macro that doesn't
+// actually do what it was intended to.
+
+#define NSSTRINGWRAPPER(bytes,len) \
+ [[[NSString alloc] initWithBytesNoCopy: (void*)(bytes) length: (len) encoding: NSUTF8StringEncoding freeWhenDone: (BOOL)0] autorelease]
+
+#define UTIL_AUTORELEASE_CF_AS_ID(cf) ( (((void*)0) == (cf)) ? ((void*)0) : [(id) CFMakeCollectable( (CFTypeRef) cf) autorelease] )
+
+#define UTIL_AUTORELEASE_CF_AS_ID_WITHOUT_TEST(cf) ( [(id) CFMakeCollectable( (CFTypeRef) cf) autorelease] )
+
+static char *lorem = "fooBarBaz";
+
+void NSLog(NSString *, ...);
+
+int main (int argc, const char * argv[]) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSString *tmp1 = NSSTRINGWRAPPER(lorem, 6); // no-warning
+ NSString *tmp2 = UTIL_AUTORELEASE_CF_AS_ID( CFStringCreateWithFormat(((void*)0), ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "lorem: %@" "")), tmp1) ); // expected-warning 2 {{leak}}
+ NSString *tmp3 = UTIL_AUTORELEASE_CF_AS_ID_WITHOUT_TEST( CFStringCreateWithFormat(((void*)0), ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "lorem: %@" "")), tmp1) );
+ NSLog(@"tmp2: %@ tmp3: %@", tmp2, tmp3);
+ [pool drain];
+ return 0;
+}
diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m
new file mode 100644
index 0000000..1ed138e
--- /dev/null
+++ b/test/Analysis/PR2978.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-missing-dealloc %s -verify
+
+// Tests for the checker which checks missing/extra ivar 'release' calls
+// in dealloc.
+
+@interface NSObject
+- (void)release;
+- dealloc;
+@end
+
+@interface MyClass : NSObject {
+@private
+ id _X;
+ id _Y;
+ id _Z;
+ id _K;
+ id _N;
+ id _M;
+ id _V;
+ id _W;
+}
+@property(retain) id X;
+@property(retain) id Y;
+@property(assign) id Z;
+@property(assign) id K;
+@property(readonly) id N;
+@property(retain) id M;
+@property(retain) id V;
+@property(retain) id W;
+-(id) O;
+-(void) setO: (id) arg;
+@end
+
+@implementation MyClass
+@synthesize X = _X;
+@synthesize Y = _Y; // expected-warning{{The '_Y' instance variable was retained by a synthesized property but wasn't released in 'dealloc'}}
+@synthesize Z = _Z; // expected-warning{{The '_Z' instance variable was not retained by a synthesized property but was released in 'dealloc'}}
+@synthesize K = _K;
+@synthesize N = _N;
+@synthesize M = _M;
+@synthesize V = _V;
+@synthesize W = _W; // expected-warning{{The '_W' instance variable was retained by a synthesized property but wasn't released in 'dealloc'}}
+
+-(id) O{ return 0; }
+-(void) setO:(id)arg { }
+
+- (id)dealloc
+{
+ [_X release];
+ [_Z release];
+ [_N release];
+
+ self.M = 0; // This will release '_M'
+ [self setV:0]; // This will release '_V'
+ [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
new file mode 100644
index 0000000..3fed57e
--- /dev/null
+++ b/test/Analysis/PR3991.m
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+
+//===----------------------------------------------------------------------===//
+// Delta-debugging produced forward declarations.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end @interface NSObject <NSObject> {
+}
+@end extern id <NSObject> NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone);
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding> - (unsigned)count;
+@end @class NSTimer, NSPort, NSArray;
+@class NSURLHandle, NSMutableArray, NSMutableData, NSData, NSURL;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end @class NSBitmapImageRep, NSCursor, NSGraphicsContext, NSImage, NSPasteboard, NSScrollView, NSWindow, NSAttributedString;
+@interface NSView : NSResponder {
+ struct __VFlags2 {
+ }
+ _vFlags2;
+}
+@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+@interface NSBox : NSView {
+}
+@end @class GDataFeedDocList, GDataServiceTicket, GDataServiceTicket, IHGoogleDocsAdapter;
+@protocol IHGoogleDocsAdapterDelegate - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError;
+@end @interface IHGoogleDocsAdapter : NSObject {
+}
+- (NSArray *)entries;
+@end extern Class const kGDataUseRegisteredClass ;
+@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList;
+- (NSArray *)directoryPathComponents;
+- (unsigned int)currentPathComponentIndex;
+- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex;
+- (NSURL *)folderFeedURL;
+@end
+
+@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { // expected-warning {{incomplete implementation}} \
+// expected-warning {{method definition for 'entries' not found}} \
+// expected-warning {{method definition for 'feedDocList' not found}} \
+// expected-warning {{method definition for 'directoryPathComponents' not found}} \
+// expected-warning {{method definition for 'currentPathComponentIndex' not found}} \
+// expected-warning {{method definition for 'setCurrentPathComponentIndex:' not found}} \
+// expected-warning {{method definition for 'folderFeedURL' not found}}
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Actual test case:
+//
+// The analyzer currently doesn't reason about ObjCKVCRefExpr. Have both
+// GRExprEngine::Visit and GRExprEngine::VisitLValue have such expressions
+// evaluate to UnknownVal.
+//===----------------------------------------------------------------------===//
+
+- (void)docListListFetchTicket:(GDataServiceTicket *)ticket finishedWithFeed:(GDataFeedDocList *)feed {
+ BOOL doGetDir = self.directoryPathComponents != 0 && self.currentPathComponentIndex < [self.directoryPathComponents count];
+ if (doGetDir) {
+ BOOL isDirExisting = [[self.feedDocList entries] count] > 0;
+ if (isDirExisting) {
+ if (self.folderFeedURL != 0) {
+ if (++self.currentPathComponentIndex == [self.directoryPathComponents count]) {
+ }
+ }
+ }
+ }
+}
+@end
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
new file mode 100644
index 0000000..3e46a0a
--- /dev/null
+++ b/test/Analysis/array-struct.c
@@ -0,0 +1,180 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+struct s {
+ int data;
+ int data_array[10];
+};
+
+typedef struct {
+ int data;
+} STYPE;
+
+void g(char *p);
+void g1(struct s* p);
+
+// Array to pointer conversion. Array in the struct field.
+void f(void) {
+ int a[10];
+ int (*p)[10];
+ p = &a;
+ (*p)[3] = 1;
+
+ struct s d;
+ struct s *q;
+ q = &d;
+ q->data = 3;
+ d.data_array[9] = 17;
+}
+
+// StringLiteral in lvalue context and pointer to array type.
+// p: ElementRegion, q: StringRegion
+void f2() {
+ char *p = "/usr/local";
+ char (*q)[4];
+ q = &"abc";
+}
+
+// Typedef'ed struct definition.
+void f3() {
+ STYPE s;
+}
+
+// Initialize array with InitExprList.
+void f4() {
+ int a[] = { 1, 2, 3};
+ int b[3] = { 1, 2 };
+ struct s c[] = {{1,{1}}};
+}
+
+// Struct variable in lvalue context.
+// Assign UnknownVal to the whole struct.
+void f5() {
+ struct s data;
+ g1(&data);
+}
+
+// AllocaRegion test.
+void f6() {
+ char *p;
+ p = __builtin_alloca(10);
+ g(p);
+ char c = *p;
+ p[1] = 'a';
+ // Test if RegionStore::EvalBinOp converts the alloca region to element
+ // region.
+ p += 2;
+}
+
+struct s2;
+
+void g2(struct s2 *p);
+
+// Incomplete struct pointer used as function argument.
+void f7() {
+ struct s2 *p = __builtin_alloca(10);
+ g2(p);
+}
+
+// sizeof() is unsigned while -1 is signed in array index.
+void f8() {
+ int a[10];
+ a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
+}
+
+// Initialization of struct array elements.
+void f9() {
+ struct s a[10];
+}
+
+// Initializing array with string literal.
+void f10() {
+ char a1[4] = "abc";
+ char a3[6] = "abc";
+}
+
+// Retrieve the default value of element/field region.
+void f11() {
+ struct s a;
+ g1(&a);
+ if (a.data == 0) // no-warning
+ a.data = 1;
+}
+
+// Convert unsigned offset to signed when creating ElementRegion from
+// SymbolicRegion.
+void f12(int *list) {
+ unsigned i = 0;
+ list[i] = 1;
+}
+
+struct s1 {
+ struct s2 {
+ int d;
+ } e;
+};
+
+// The binding of a.e.d should not be removed. Test recursive subregion map
+// building: a->e, e->d. Only then 'a' could be added to live region roots.
+void f13(double timeout) {
+ struct s1 a;
+ a.e.d = (int) timeout;
+ if (a.e.d == 10)
+ a.e.d = 4;
+}
+
+struct s3 {
+ int a[2];
+};
+
+static struct s3 opt;
+
+// Test if the embedded array is retrieved correctly.
+void f14() {
+ struct s3 my_opt = opt;
+}
+
+void bar(int*);
+
+// Test if the array is correctly invalidated.
+void f15() {
+ int a[10];
+ bar(a);
+ if (a[1]) // no-warning
+ (void)1;
+}
+
+struct s3 p[1];
+
+// Code from postgresql.
+// Current cast logic of region store mistakenly leaves the final result region
+// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
+// assigns to 'a'.
+void f16(struct s3 *p) {
+ struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+}
+
+void inv(struct s1 *);
+
+// Invalidate the struct field.
+void f17() {
+ struct s1 t;
+ int x;
+ inv(&t);
+ if (t.e.d)
+ x = 1;
+}
+
+void read(char*);
+
+void f18() {
+ char *q;
+ char *p = (char *) __builtin_alloca(10);
+ read(p);
+ q = p;
+ q++;
+ if (*q) { // no-warning
+ }
+}
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
new file mode 100644
index 0000000..029aefc
--- /dev/null
+++ b/test/Analysis/blocks.m
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from Mac OS X headers:
+//===----------------------------------------------------------------------===//
+
+typedef __builtin_va_list va_list;
+typedef unsigned int uint32_t;
+typedef struct dispatch_queue_s *dispatch_queue_t;
+typedef struct dispatch_queue_attr_s *dispatch_queue_attr_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+__attribute__((visibility("default"))) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__nothrow__)) dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
+typedef long dispatch_once_t;
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@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)alloc;
+@end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithFormat:(NSString *)format arguments:(va_list)argList __attribute__((format(__NSString__, 1, 0)));
+@end
+@class NSString, NSData;
+typedef struct cssm_sample {} CSSM_SAMPLEGROUP, *CSSM_SAMPLEGROUP_PTR;
+typedef struct __aslclient *aslclient;
+typedef struct __aslmsg *aslmsg;
+aslclient asl_open(const char *ident, const char *facility, uint32_t opts);
+int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));
+
+//===----------------------------------------------------------------------===//
+// Begin actual test cases.
+//===----------------------------------------------------------------------===//
+
+// test1 - This test case exposed logic that caused the analyzer to crash because of a memory bug
+// in BlockDataRegion. It represents real code that contains two block literals. Eventually
+// via IPA 'logQueue' and 'client' should be updated after the call to 'dispatch_once'.
+void test1(NSString *format, ...) {
+ static dispatch_queue_t logQueue;
+ static aslclient client;
+ static dispatch_once_t pred;
+ do {
+ if (__builtin_expect(*(&pred), ~0l) != ~0l)
+ dispatch_once(&pred, ^{
+ logQueue = dispatch_queue_create("com.mycompany.myproduct.asl", ((void*)0));
+ client = asl_open(((void*)0), "com.mycompany.myproduct", 0);
+ });
+ } while (0);
+
+ va_list args;
+ __builtin_va_start(args, format);
+
+ NSString *str = [[NSString alloc] initWithFormat:format arguments:args];
+ dispatch_async(logQueue, ^{ asl_log(client, ((void*)0), 4, "%s", [str UTF8String]); });
+ [str release];
+
+ __builtin_va_end(args);
+}
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
new file mode 100644
index 0000000..1cb88e6
--- /dev/null
+++ b/test/Analysis/casts.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// Test if the 'storage' region gets properly initialized after it is cast to
+// 'struct sockaddr *'.
+
+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 getsockname();
+
+void f(int sock) {
+ struct sockaddr_storage storage;
+ struct sockaddr* sockaddr = (struct sockaddr*)&storage;
+ socklen_t addrlen = sizeof(storage);
+ getsockname(sock, sockaddr, &addrlen);
+ switch (sockaddr->sa_family) { // no-warning
+ default:
+ ;
+ }
+}
+
+struct s {
+ struct s *value;
+};
+
+void f1(struct s **pval) {
+ int *tbool = ((void*)0);
+ struct s *t = *pval;
+ pval = &(t->value);
+ 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) // here load the element region with the correct type 'int'
+ (void)3;
+}
+
+void f2(const char *str) {
+ unsigned char ch, cl, *p;
+
+ p = (unsigned char *)str;
+ ch = *p++; // use cast-to type 'unsigned char' to create element region.
+ cl = *p++;
+ if(!cl)
+ cl = 'a';
+}
+
+// Test cast VariableSizeArray to pointer does not crash.
+void *memcpy(void *, void const *, unsigned long);
+typedef unsigned char Byte;
+void doit(char *data, int len) {
+ if (len) {
+ Byte buf[len];
+ memcpy(buf, data, len);
+ }
+}
+
+// PR 6013 and 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator.
+void pr6013_6035_test(void *p) {
+ unsigned int foo;
+ foo = ((long)(p));
+ (void) foo;
+}
diff --git a/test/Analysis/casts.m b/test/Analysis/casts.m
new file mode 100644
index 0000000..c99b4d6
--- /dev/null
+++ b/test/Analysis/casts.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// Test function pointer casts. Currently we track function addresses using
+// loc::FunctionVal. Because casts can be arbitrary, do we need to model
+// functions with regions?
+typedef void* (*MyFuncTest1)(void);
+
+MyFuncTest1 test1_aux(void);
+void test1(void) {
+ void *x;
+ void* (*p)(void);
+ p = ((void*) test1_aux());
+ if (p != ((void*) 0)) x = (*p)();
+}
+
+// Test casts from void* to function pointers. Same issue as above:
+// should we eventually model function pointers using regions?
+void* test2(void *p) {
+ MyFuncTest1 fp = (MyFuncTest1) p;
+ return (*fp)();
+}
diff --git a/test/Analysis/cfref_PR2519.c b/test/Analysis/cfref_PR2519.c
new file mode 100644
index 0000000..ebf3544
--- /dev/null
+++ b/test/Analysis/cfref_PR2519.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+typedef unsigned char Boolean;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+typedef struct {} CFAllocatorContext;
+extern void CFRelease(CFTypeRef cf);
+typedef struct {}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+extern CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+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 struct __CFNotificationCenter * CFNotificationCenterRef;
+extern CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
+extern void CFNotificationCenterPostNotification(CFNotificationCenterRef center, CFStringRef name, const void *object, CFDictionaryRef userInfo, Boolean deliverImmediately);
+
+// This test case was reported in PR2519 as a false positive (_value was
+// reported as being leaked).
+
+int main(int argc, char **argv) {
+ CFStringRef _key = ((CFStringRef) __builtin___CFStringMakeConstantString ("" "Process identifier" ""));
+ int pid = 42;
+
+ CFNumberRef _value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
+ CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&_key, (const void **)&_value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(_value); // no-warning
+ CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
+ ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlPreferencesChanged" "")),
+ ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlUserDefaults" "")),
+ userInfo, 0);
+ CFRelease(userInfo); // no-warning
+
+ return 0;
+}
+
diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c
new file mode 100644
index 0000000..12b0819
--- /dev/null
+++ b/test/Analysis/cfref_rdar6080742.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+// This test case was reported in <rdar:problem/6080742>.
+// It tests path-sensitivity with respect to '!(cfstring != 0)' (negation of inequality).
+
+int printf(const char *restrict,...);
+typedef unsigned long UInt32;
+typedef signed long SInt32;
+typedef SInt32 OSStatus;
+typedef unsigned char Boolean;
+enum { noErr = 0};
+typedef const void *CFTypeRef;
+typedef const struct __CFString *CFStringRef;
+typedef const struct __CFAllocator *CFAllocatorRef;
+extern void CFRelease(CFTypeRef cf);
+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};
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+
+enum { memROZWarn = -99, memROZError = -99, memROZErr = -99, memFullErr = -108,
+ nilHandleErr = -109, memWZErr = -111, memPurErr = -112, memAdrErr = -110,
+ memAZErr = -113, memPCErr = -114, memBCErr = -115, memSCErr = -116, memLockedErr = -117};
+
+#define DEBUG1
+
+void DebugStop(const char *format,...);
+void DebugTraceIf(unsigned int condition, const char *format,...);
+Boolean DebugDisplayOSStatusMsg(OSStatus status, const char *statusStr, const char *fileName, unsigned long lineNumber);
+
+#define Assert(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
+#define AssertMsg(condition, message)if (!(condition)) { DebugStop("Assertion failure: %s (%s) [File: %s, Line: %lu]", #condition, message, __FILE__, __LINE__); }
+#define Require(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
+#define RequireAction(condition, action)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); action }
+#define RequireActionSilent(condition, action)if (!(condition)) { action }
+#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. */
+
+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;
+}
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
new file mode 100644
index 0000000..bb2b2fe
--- /dev/null
+++ b/test/Analysis/complex.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -Wno-unreachable-code %s
+
+#include <stdint.h>
+
+void f1(int * p) {
+
+ // This branch should be infeasible
+ // because __imag__ p is 0.
+ if (!p && __imag__ (intptr_t) p)
+ *p = 1; // no-warning
+
+ // If p != 0 then this branch is feasible; otherwise it is not.
+ if (__real__ (intptr_t) p)
+ *p = 1; // no-warning
+
+ *p = 2; // expected-warning{{Dereference of null pointer}}
+}
diff --git a/test/Analysis/concrete-address.c b/test/Analysis/concrete-address.c
new file mode 100644
index 0000000..07ca713
--- /dev/null
+++ b/test/Analysis/concrete-address.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+void foo() {
+ int *p = (int*) 0x10000; // Should not crash here.
+ *p = 3;
+}
diff --git a/test/Analysis/conditional-op-missing-lhs.c b/test/Analysis/conditional-op-missing-lhs.c
new file mode 100644
index 0000000..86882a5
--- /dev/null
+++ b/test/Analysis/conditional-op-missing-lhs.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -warn-uninit-values -verify %s
+
+void f1()
+{
+ int i;
+
+ int j = i ? : 1; // expected-warning{{use of uninitialized variable}} //expected-warning{{Value stored to 'j' during its initialization is never read}}
+}
+
+void *f2(int *i)
+{
+ return i ? : 0;
+}
+
+void *f3(int *i)
+{
+ int a;
+
+ return &a ? : i;
+}
+
+void f4()
+{
+ char c[1 ? : 2];
+}
+
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
new file mode 100644
index 0000000..a002174
--- /dev/null
+++ b/test/Analysis/dead-stores.c
@@ -0,0 +1,431 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+
+void f1() {
+ int k, y;
+ int abc=1;
+ long idx=abc+3*5; // expected-warning {{never read}}
+}
+
+void f2(void *b) {
+ char *c = (char*)b; // no-warning
+ char *d = b+1; // expected-warning {{never read}}
+ printf("%s", c); // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+ // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+}
+
+int f();
+
+void f3() {
+ int r;
+ if ((r = f()) != 0) { // no-warning
+ int y = r; // no-warning
+ printf("the error is: %d\n", y);
+ }
+}
+
+void f4(int k) {
+
+ k = 1;
+
+ if (k)
+ f1();
+
+ k = 2; // expected-warning {{never read}}
+}
+
+void f5() {
+
+ int x = 4; // no-warning
+ int *p = &x; // expected-warning{{never read}}
+
+}
+
+int f6() {
+
+ int x = 4;
+ ++x; // expected-warning{{never read}}
+ return 1;
+}
+
+int f7(int *p) {
+ // This is allowed for defensive programming.
+ p = 0; // no-warning
+ return 1;
+}
+
+int f7b(int *p) {
+ // This is allowed for defensive programming.
+ p = (0); // no-warning
+ return 1;
+}
+
+int f7c(int *p) {
+ // This is allowed for defensive programming.
+ p = (void*) 0; // no-warning
+ return 1;
+}
+
+int f7d(int *p) {
+ // This is allowed for defensive programming.
+ p = (void*) (0); // no-warning
+ return 1;
+}
+
+int f8(int *p) {
+ extern int *baz();
+ if ((p = baz())) // expected-warning{{Although the value}}
+ return 1;
+ return 0;
+}
+
+int f9() {
+ int x = 4;
+ x = x + 10; // expected-warning{{never read}}
+ return 1;
+}
+
+int f10() {
+ int x = 4;
+ x = 10 + x; // expected-warning{{never read}}
+ return 1;
+}
+
+int f11() {
+ int x = 4;
+ return x++; // expected-warning{{never read}}
+}
+
+int f11b() {
+ int x = 4;
+ return ((((++x)))); // no-warning
+}
+
+int f12a(int y) {
+ int x = y; // expected-warning{{never read}}
+ return 1;
+}
+int f12b(int y) {
+ int x __attribute__((unused)) = y; // no-warning
+ return 1;
+}
+
+// Filed with PR 2630. This code should produce no warnings.
+int f13(void)
+{
+ int a = 1;
+ int b, c = b = a + a;
+
+ if (b > 0)
+ return (0);
+
+ return (a + b + c);
+}
+
+// Filed with PR 2763.
+int f14(int count) {
+ int index, nextLineIndex;
+ for (index = 0; index < count; index = nextLineIndex+1) {
+ nextLineIndex = index+1; // no-warning
+ continue;
+ }
+ return index;
+}
+
+// Test case for <rdar://problem/6248086>
+void f15(unsigned x, unsigned y) {
+ int count = x * y; // no-warning
+ int z[count];
+}
+
+int f16(int x) {
+ x = x * 2;
+ x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}}
+ ? 5 : 8;
+ return x;
+}
+
+// Self-assignments should not be flagged as dead stores.
+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...".
+int f18() {
+ int x = 0; // no-warning
+ if (1)
+ x = 10; // expected-warning{{Value stored to 'x' is never read}}
+ while (1)
+ x = 10; // expected-warning{{Value stored to 'x' is never read}}
+ do
+ x = 10; // expected-warning{{Value stored to 'x' is never read}}
+ while (1);
+
+ return (x = 10); // expected-warning{{Although the value stored to 'x' is used in the enclosing expression, the value is never actually read from 'x'}}
+}
+
+// PR 3514: false positive `dead initialization` warning for init to global
+// http://llvm.org/bugs/show_bug.cgi?id=3514
+extern const int MyConstant;
+int f19(void) {
+ int x = MyConstant; // no-warning
+ x = 1;
+ return x;
+}
+
+int f19b(void) { // This case is the same as f19.
+ const int MyConstant = 0;
+ int x = MyConstant; // no-warning
+ x = 1;
+ return x;
+}
+
+void f20(void) {
+ int x = 1; // no-warning
+#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;
+ }
+}
+
+void f23_aux(const char* s);
+void f23(int argc, char **argv) {
+ int shouldLog = (argc > 1); // no-warning
+ ^{
+ if (shouldLog) f23_aux("I did too use it!\n");
+ else f23_aux("I shouldn't log. Wait.. d'oh!\n");
+ }();
+}
+
+void f23_pos(int argc, char **argv) {
+ int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}}
+ ^{
+ f23_aux("I did too use it!\n");
+ }();
+}
+
+void f24_A(int y) {
+ // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
+ int x = (y > 2); // no-warning
+ ^ {
+ int z = x + y; // FIXME: Eventually this should be reported as a dead store.
+ }();
+}
+
+void f24_B(int y) {
+ // FIXME: One day this should be reported as dead since 'x' is just overwritten.
+ __block int x = (y > 2); // no-warning
+ ^{
+ // FIXME: This should eventually be a dead store since it is never read either.
+ x = 5; // no-warning
+ }();
+}
+
+int f24_C(int y) {
+ // FIXME: One day this should be reported as dead since 'x' is just overwritten.
+ __block int x = (y > 2); // no-warning
+ ^{
+ x = 5; // no-warning
+ }();
+ return x;
+}
+
+int f24_D(int y) {
+ __block int x = (y > 2); // no-warning
+ ^{
+ if (y > 4)
+ x = 5; // no-warning
+ }();
+ return x;
+}
+
+// This example shows that writing to a variable captured by a block means that it might
+// not be dead.
+int f25(int y) {
+ __block int x = (y > 2);
+ __block int z = 0;
+ void (^foo)() = ^{ z = x + y; };
+ x = 4; // no-warning
+ foo();
+ return z;
+}
+
+// This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
+// stores for variables that are just marked '__block' is overly conservative.
+int f25_b(int y) {
+ // FIXME: we should eventually report a dead store here.
+ __block int x = (y > 2);
+ __block int z = 0;
+ x = 4; // no-warning
+ return z;
+}
+
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
new file mode 100644
index 0000000..22d446e
--- /dev/null
+++ b/test/Analysis/dead-stores.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -verify -Wno-unreachable-code %s
+
+//===----------------------------------------------------------------------===//
+// Basic dead store checking (but in C++ mode).
+//===----------------------------------------------------------------------===//
+
+int j;
+void test1() {
+ int x = 4;
+
+ ++x; // expected-warning{{never read}}
+
+ switch (j) {
+ case 1:
+ throw 1;
+ (void)x;
+ break;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Dead store checking involving constructors.
+//===----------------------------------------------------------------------===//
+
+class Test2 {
+ int &x;
+public:
+ Test2(int &y) : x(y) {}
+ ~Test2() { ++x; }
+};
+
+int test2(int x) {
+ { Test2 a(x); } // no-warning
+ return x;
+}
+
+//===----------------------------------------------------------------------===//
+// Dead store checking involving CXXTemporaryExprs
+//===----------------------------------------------------------------------===//
+
+namespace TestTemp {
+ template<typename _Tp>
+ class pencil {
+ public:
+ ~pencil() throw() {}
+ };
+ template<typename _Tp, typename _Number2> struct _Row_base {
+ _Row_base(const pencil<_Tp>& x) {}
+ };
+ template<typename _Tp, typename _Number2 = TestTemp::pencil<_Tp> >
+ class row : protected _Row_base<_Tp, _Number2> {
+ typedef _Row_base<_Tp, _Number2> _Base;
+ typedef _Number2 pencil_type;
+ public:
+ explicit row(const pencil_type& __a = pencil_type()) : _Base(__a) {}
+ };
+}
+
+void test2_b() {
+ TestTemp::row<const char*> x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Test references.
+//===----------------------------------------------------------------------===//
+
+void test3_a(int x) {
+ ++x; // expected-warning{{never read}}
+}
+
+void test3_b(int &x) {
+ ++x; // no-warninge
+}
+
+void test3_c(int x) {
+ int &y = x;
+ // Shows the limitation of dead stores tracking. The write is really
+ // dead since the value cannot escape the function.
+ ++y; // no-warning
+}
+
+void test3_d(int &x) {
+ int &y = x;
+ ++y; // no-warning
+}
+
+void test3_e(int &x) {
+ int &y = x;
+}
+
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
new file mode 100644
index 0000000..765a24a
--- /dev/null
+++ b/test/Analysis/dead-stores.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; @end
+typedef float CGFloat;
+typedef struct _NSPoint {} NSRange;
+@interface NSValue (NSValueRangeExtensions) + (NSValue *)valueWithRange:(NSRange)range;
+- (BOOL)containsObject:(id)anObject;
+@end
+@class NSURLAuthenticationChallenge;
+@interface NSResponder : NSObject <NSCoding> {} @end
+@class NSArray, NSDictionary, NSString;
+@interface NSObject (NSKeyValueBindingCreation)
++ (void)exposeBinding:(NSString *)binding;
+- (NSArray *)exposedBindings;
+@end
+extern NSString *NSAlignmentBinding;
+
+// This test case was reported as a false positive due to a bug in the
+// LiveVariables <-> DeadStores interplay. We should not flag a warning
+// here. The test case was reported in:
+// http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-July/002157.html
+void DeadStoreTest(NSObject *anObject) {
+ NSArray *keys;
+ if ((keys = [anObject exposedBindings]) && // no-warning
+ ([keys containsObject:@"name"] && [keys containsObject:@"icon"])) {}
+}
+
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
new file mode 100644
index 0000000..18b4241
--- /dev/null
+++ b/test/Analysis/delegates.m
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+void CFRelease(CFTypeRef cf);
+typedef const struct __CFDictionary * CFDictionaryRef;
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
+extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+typedef signed char BOOL;
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef struct objc_selector *SEL;
+@class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef NSInteger NSComparisonResult;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (oneway void)release;
+- (Class)class;
+- (id)retain;
+@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;
++ (id)alloc;
++ (Class)class;
+- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
+@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;
+typedef struct _NSRange {} NSRange;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSMutableArray : NSArray
+- (void)addObject:(id)anObject;
+- (id)initWithCapacity:(NSUInteger)numItems;
+@end
+typedef unsigned short unichar;
+@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
+typedef NSUInteger NSStringCompareOptions;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+- (NSComparisonResult)compare:(NSString *)string;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
+- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
+- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
+- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
+@end
+@interface NSSimpleCString : NSString {} @end
+@interface NSConstantString : NSSimpleCString @end
+extern void *_NSConstantStringClassReference;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+// <rdar://problem/6062730>
+// The analyzer doesn't perform any inter-procedural analysis, so delegates
+// involving [NSObject performSelector...] tend to lead to false positives.
+// For now the analyzer just stops tracking the reference count of the
+// receiver until we have better support for delegates.
+
+@interface test_6062730 : NSObject
++ (void)postNotification:(NSString *)str;
+- (void)foo;
+- (void)bar;
+@end
+
+@implementation test_6062730
+- (void) foo {
+ NSString *str = [[NSString alloc] init];
+ [test_6062730 performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
+}
+
+- (void) bar {
+ NSString *str = [[NSString alloc] init]; // expected-warning{{leak}}
+ // FIXME: We need to resolve [self class] to 'test_6062730'.
+ [[self class] performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
+}
+
++ (void) postNotification:(NSString *)str {
+ [str release]; // no-warning
+}
+@end
+
diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c
new file mode 100644
index 0000000..08ffe32
--- /dev/null
+++ b/test/Analysis/elementtype.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s
+
+typedef struct added_obj_st {
+ int type;
+} ADDED_OBJ;
+
+// Test if we are using the canonical type for ElementRegion.
+void f() {
+ ADDED_OBJ *ao[4]={((void*)0),((void*)0),((void*)0),((void*)0)};
+ if (ao[0] != ((void*)0)) {
+ ao[0]->type=0;
+ }
+}
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
new file mode 100644
index 0000000..0a95b70
--- /dev/null
+++ b/test/Analysis/exercise-ps.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+//
+// Just exercise the analyzer on code that has at one point caused issues
+// (i.e., no assertions or crashes).
+
+
+static void f1(const char *x, char *y) {
+ while (*x != 0) {
+ *y++ = *x++;
+ }
+}
+
+// This following case checks that we properly handle typedefs when getting
+// the RvalueType of an ElementRegion.
+typedef struct F12_struct {} F12_typedef;
+typedef void* void_typedef;
+void_typedef f2_helper();
+static void f2(void *buf) {
+ F12_typedef* x;
+ x = f2_helper();
+ memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring C library function 'memcpy' with type 'void *(void *, void const *}} \
+ // expected-note{{please include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
+}
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
new file mode 100644
index 0000000..c97d4f8
--- /dev/null
+++ b/test/Analysis/fields.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=region -verify
+
+unsigned foo();
+typedef struct bf { unsigned x:2; } bf;
+void bar() {
+ bf y;
+ *(unsigned*)&y = foo();
+ y.x = 1;
+}
+
+struct s {
+ int n;
+};
+
+void f() {
+ struct s a;
+ int *p = &(a.n) + 1;
+}
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
new file mode 100644
index 0000000..53c873d
--- /dev/null
+++ b/test/Analysis/func.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+void f(void) {
+ void (*p)(void);
+ p = f;
+ p = &f;
+ p();
+ (*p)();
+}
+
+void g(void (*fp)(void));
+
+void f2() {
+ g(f);
+}
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
new file mode 100644
index 0000000..518ab82
--- /dev/null
+++ b/test/Analysis/malloc.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-experimental-checks -analyzer-store=region -verify %s
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+void *realloc(void *ptr, size_t size);
+void *calloc(size_t nmemb, size_t size);
+
+void f1() {
+ int *p = malloc(10);
+ return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void f1_b() {
+ int *p = malloc(10); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void f2() {
+ int *p = malloc(10);
+ free(p);
+ free(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+// This case tests that storing malloc'ed memory to a static variable which is
+// then returned is not leaked. In the absence of known contracts for functions
+// or inter-procedural analysis, this is a conservative answer.
+int *f3() {
+ static int *p = 0;
+ p = malloc(10);
+ return p; // no-warning
+}
+
+// This case tests that storing malloc'ed memory to a static global variable
+// which is then returned is not leaked. In the absence of known contracts for
+// functions or inter-procedural analysis, this is a conservative answer.
+static int *p_f4 = 0;
+int *f4() {
+ p_f4 = malloc(10);
+ return p_f4; // no-warning
+}
+
+int *f5() {
+ int *q = malloc(10);
+ q = realloc(q, 20);
+ return q; // no-warning
+}
+
+void f6() {
+ int *p = malloc(10);
+ if (!p)
+ return; // no-warning
+ else
+ free(p);
+}
+
+char *doit2();
+void pr6069() {
+ char *buf = doit2();
+ free(buf);
+}
diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m
new file mode 100644
index 0000000..0dbd6cb
--- /dev/null
+++ b/test/Analysis/misc-ps-64.m
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s
+
+// <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
+// these expressions and building CFGs. These tests are here to prevent
+// regressions.
+typedef long long int64_t;
+@class NSString, NSDictionary;
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef unsigned char Boolean;
+typedef const struct __CFDictionary * CFDictionaryRef;
+
+extern Boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, const void *key, const void **value);
+static void shazam(NSUInteger i, unsigned char **out);
+
+void rdar_6440393_1(NSDictionary *dict) {
+ NSInteger x = 0;
+ unsigned char buf[10], *bufptr = buf;
+ if (!CFDictionaryGetValueIfPresent(0, dict, (void *)&x))
+ return;
+ shazam(x, &bufptr);
+}
+
+// <rdar://problem/6845148> - In this example we got a signedness
+// mismatch between the literal '0' and the value of 'scrooge'. The
+// trick is to have the evaluator convert the literal to an unsigned
+// integer when doing a comparison with the pointer. This happens
+// because of the transfer function logic of
+// OSAtomicCompareAndSwap64Barrier, which doesn't have special casts
+// in place to do this for us.
+_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+extern id objc_lookUpClass(const char *name);
+void rdar_6845148(id debug_yourself) {
+ if (!debug_yourself) {
+ const char *wacky = ((void *)0);
+ Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);
+ OSAtomicCompareAndSwap64Barrier(0, (int64_t)scrooge, (int64_t*)&debug_yourself);
+ }
+}
+void rdar_6845148_b(id debug_yourself) {
+ if (!debug_yourself) {
+ const char *wacky = ((void *)0);
+ Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);
+ OSAtomicCompareAndSwap64Barrier((int64_t)scrooge, 0, (int64_t*)&debug_yourself);
+ }
+}
diff --git a/test/Analysis/misc-ps-basic-store.m b/test/Analysis/misc-ps-basic-store.m
new file mode 100644
index 0000000..4f8e4f6
--- /dev/null
+++ b/test/Analysis/misc-ps-basic-store.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify -fblocks %s
+
+//---------------------------------------------------------------------------
+// Test case 'checkaccess_union' differs for region store and basic store.
+// The basic store doesn't reason about compound literals, so the code
+// below won't fire an "uninitialized value" warning.
+//---------------------------------------------------------------------------
+
+// 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 { // no-warning
+ __typeof (status) __in; int __i;}
+ )
+ {
+ .__in = (status)}
+ ).__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-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m
new file mode 100644
index 0000000..a986b8e
--- /dev/null
+++ b/test/Analysis/misc-ps-eager-assume.m
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s -analyzer-eagerly-assume
+
+// Delta-reduced header stuff (needed for test cases).
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+- (oneway void)release;
+@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)alloc;
+@end typedef struct {}
+NSFastEnumerationState;
+@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@end @interface NSMutableArray : NSArray - (void)addObject:(id)anObject;
+- (BOOL)isEqualToString:(NSString *)aString;
+@end @interface NSAutoreleasePool : NSObject {}
+- (void)drain;
+- (id)init;
+@end
+
+// This test case tests that (x != 0) is eagerly evaluated before stored to
+// 'y'. This test case complements recoverCastedSymbol (see below) because
+// the symbolic expression is stored to 'y' (which is a short instead of an
+// int). recoverCastedSymbol() only recovers path-sensitivity when the
+// symbolic expression is literally the branch condition.
+//
+void handle_assign_of_condition(int x) {
+ // The cast to 'short' causes us to lose symbolic constraint.
+ short y = (x != 0);
+ char *p = 0;
+ if (y) {
+ // This should be infeasible.
+ if (!(x != 0)) {
+ *p = 1; // no-warning
+ }
+ }
+}
+
+// From <rdar://problem/6619921>
+//
+// In this test case, 'needsAnArray' is a signed char. The analyzer tracks
+// a symbolic value for this variable, but in the branch condition it is
+// promoted to 'int'. Currently the analyzer doesn't reason well about
+// promotions of symbolic values, so this test case tests the logic in
+// 'recoverCastedSymbol()' (GRExprEngine.cpp) to test that we recover
+// path-sensitivity and use the symbol for 'needsAnArray' in the branch
+// condition.
+//
+void handle_symbolic_cast_in_condition(void) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ BOOL needsAnArray = [@"aString" isEqualToString:@"anotherString"];
+ NSMutableArray* array = needsAnArray ? [[NSMutableArray alloc] init] : 0;
+ if(needsAnArray)
+ [array release];
+
+ [pool drain];
+}
+
+// From PR 3836 (http://llvm.org/bugs/show_bug.cgi?id=3836)
+//
+// In this test case, the double '!' works fine with our symbolic constraints,
+// but we don't support comparing SymConstraint != SymConstraint. By eagerly
+// assuming the truth of !!a or !!b, we can compare these values directly.
+//
+void pr3836(int *a, int *b) {
+ if (!!a != !!b) /* one of them is NULL */
+ return;
+ if (!a && !b) /* both are NULL */
+ return;
+
+ *a = 1; // no-warning
+ *b = 1; // no-warning
+}
+
+
+//===---------------------------------------------------------------------===//
+// <rdar://problem/7342806>
+// This false positive occured because the symbolic constraint on a short was
+// not maintained via sign extension. The analyzer doesn't properly handle
+// the sign extension, but now tracks the constraint. This particular
+// case relies on -analyzer-eagerly-assume because of the expression
+// 'Flag1 != Count > 0'.
+//===---------------------------------------------------------------------===//
+
+void rdar7342806_aux(short x);
+
+void rdar7342806() {
+ extern short Count;
+ extern short Flag1;
+
+ short *Pointer = 0;
+ short Flag2 = !!Pointer; // Flag2 is false (0).
+ short Ok = 1;
+ short Which;
+
+ if( Flag1 != Count > 0 )
+ // Static analyzer skips this so either
+ // Flag1 is true and Count > 0
+ // or
+ // Flag1 is false and Count <= 0
+ Ok = 0;
+
+ if( Flag1 != Flag2 )
+ // Analyzer skips this so Flag1 and Flag2 have the
+ // same value, both are false because Flag2 is false. And
+ // from that we know Count must be <= 0.
+ Ok = 0;
+
+ for( Which = 0;
+ Which < Count && Ok;
+ Which++ )
+ // This statement can only execute if Count > 0 which can only
+ // happen when Flag1 and Flag2 are both true and Flag2 will only
+ // be true when Pointer is not NULL.
+ rdar7342806_aux(*Pointer); // no-warning
+}
+
+//===---------------------------------------------------------------------===//
+// PR 5627 - http://llvm.org/bugs/show_bug.cgi?id=5627
+// This test case depends on using -analyzer-eagerly-assume and
+// -analyzer-store=region. The '-analyzer-eagerly-assume' causes the path
+// to bifurcate when evaluating the function call argument, and a state
+// caching bug in GRExprEngine::CheckerVisit (and friends) caused the store
+// to 'p' to not be evaluated along one path, but then an autotransition caused
+// the path to keep on propagating with 'p' still set to an undefined value.
+// We would then get a bogus report of returning uninitialized memory.
+// Note: CheckerVisit mistakenly cleared an existing node, and the cleared
+// node was resurrected by GRStmtNodeBuilder::~GRStmtNodeBuilder(), where
+// 'p' was not assigned.
+//===---------------------------------------------------------------------===//
+
+float *pr5627_f(int y);
+
+float *pr5627_g(int x) {
+ float *p;
+ p = pr5627_f(!x);
+ return p; // no-warning
+}
+
diff --git a/test/Analysis/misc-ps-flat-store.c b/test/Analysis/misc-ps-flat-store.c
new file mode 100644
index 0000000..8cbcecf
--- /dev/null
+++ b/test/Analysis/misc-ps-flat-store.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=flat -verify %s
+
+void f1() {
+ int x;
+ int *p;
+ x = 1;
+ p = 0;
+ if (x != 1)
+ *p = 1; // no-warning
+}
diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m
new file mode 100644
index 0000000..b1afc3d
--- /dev/null
+++ b/test/Analysis/misc-ps-ranges.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s
+
+// <rdar://problem/6776949>
+// main's 'argc' argument is always > 0
+int main(int argc, char* argv[]) {
+ int *p = 0;
+
+ if (argc == 0)
+ *p = 1;
+
+ if (argc == 1)
+ return 1;
+
+ int x = 1;
+ int i;
+
+ for(i=1;i<argc;i++){
+ p = &x;
+ }
+
+ return *p; // no-warning
+}
+
+// PR 5969: the comparison of argc < 3 || argc > 4 should constraint the switch
+// statement from having the 'default' branch taken. This previously reported a false
+// positive with the use of 'v'.
+
+int pr5969(int argc, char *argv[]) {
+
+ int v;
+
+ if ((argc < 3) || (argc > 4)) return 0;
+
+ switch(argc) {
+ case 3:
+ v = 33;
+ break;
+ case 4:
+ v = 44;
+ break;
+ }
+
+ return v; // no-warning
+}
+
+int pr5969_positive(int argc, char *argv[]) {
+
+ int v;
+
+ if ((argc < 3) || (argc > 4)) return 0;
+
+ switch(argc) {
+ case 3:
+ v = 33;
+ break;
+ }
+
+ return v; // expected-warning{{Undefined or garbage value returned to caller}}
+}
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 0000000..026d4f5
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-i386.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -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 0000000..e3c6d47
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store-x86_64.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -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.cpp b/test/Analysis/misc-ps-region-store.cpp
new file mode 100644
index 0000000..6794d48
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+
+// Test basic handling of references.
+char &test1_aux();
+char *test1() {
+ return &test1_aux();
+}
+
+// Test test1_aux() evaluates to char &.
+char test1_as_rvalue() {
+ return test1_aux();
+}
+
+// Test passing a value as a reference. The 'const' in test2_aux() adds
+// an ImplicitCastExpr, which is evaluated as an lvalue.
+int test2_aux(const int &n);
+int test2(int n) {
+ return test2_aux(n);
+}
+
+int test2_b_aux(const short &n);
+int test2_b(int n) {
+ return test2_b_aux(n);
+}
+
+// Test getting the lvalue of a derived and converting it to a base. This
+// previously crashed.
+class Test3_Base {};
+class Test3_Derived : public Test3_Base {};
+
+int test3_aux(Test3_Base &x);
+int test3(Test3_Derived x) {
+ return test3_aux(x);
+}
+
+//===---------------------------------------------------------------------===//
+// Test CFG support for C++ condition variables.
+//===---------------------------------------------------------------------===//
+
+int test_init_in_condition_aux();
+int test_init_in_condition() {
+ if (int x = test_init_in_condition_aux()) { // no-warning
+ return 1;
+ }
+ return 0;
+}
+
+int test_init_in_condition_switch() {
+ switch (int x = test_init_in_condition_aux()) { // no-warning
+ case 1:
+ return 0;
+ case 2:
+ if (x == 2)
+ return 0;
+ else {
+ // Unreachable.
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+int test_init_in_condition_while() {
+ int z = 0;
+ while (int x = ++z) { // no-warning
+ if (x == 2)
+ break;
+ }
+
+ if (z == 2)
+ return 0;
+
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ return 0;
+}
+
+
+int test_init_in_condition_for() {
+ int z = 0;
+ for (int x = 0; int y = ++z; ++x) {
+ if (x == y) // no-warning
+ break;
+ }
+ if (z == 1)
+ return 0;
+
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ return 0;
+}
+
+//===---------------------------------------------------------------------===//
+// Test handling of 'this' pointer.
+//===---------------------------------------------------------------------===//
+
+class TestHandleThis {
+ int x;
+
+ TestHandleThis();
+ int foo();
+ int null_deref_negative();
+ int null_deref_positive();
+};
+
+int TestHandleThis::foo() {
+ // Assume that 'x' is initialized.
+ return x + 1; // no-warning
+}
+
+int TestHandleThis::null_deref_negative() {
+ x = 10;
+ if (x == 10) {
+ return 1;
+ }
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ return 0;
+}
+
+int TestHandleThis::null_deref_positive() {
+ x = 10;
+ if (x == 9) {
+ return 1;
+ }
+ int *p = 0;
+ *p = 0xDEADBEEF; // expected-warning{{null pointer}}
+ return 0;
+}
+
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
new file mode 100644
index 0000000..46a8720
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.m
@@ -0,0 +1,838 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+
+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
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} - (id)init; @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 NSAssertionHandler : NSObject {}
++ (NSAssertionHandler *)currentHandler;
+- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+
+#ifdef TEST_64
+typedef long long int64_t;
+typedef int64_t intptr_t;
+#else
+typedef int int32_t;
+typedef int32_t intptr_t;
+#endif
+
+//---------------------------------------------------------------------------
+// Test case 'checkaccess_union' differs for region store and basic store.
+// The basic store doesn't reason about compound literals, so the code
+// below won't fire an "uninitialized value" warning.
+//---------------------------------------------------------------------------
+
+// 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;
+ // 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;}
+ )
+ {
+ .__in = (status)}
+ ).__i))) & 0xff00) >> 8) == 1)
+ ret = 1;
+}
+
+// Check our handling of fields being invalidated by function calls.
+struct test2_struct { int x; int y; char* s; };
+void test2_help(struct test2_struct* p);
+
+char test2() {
+ struct test2_struct s;
+ test2_help(&s);
+ char *p = 0;
+
+ if (s.x > 1) {
+ if (s.s != 0) {
+ p = "hello";
+ }
+ }
+
+ if (s.x > 1) {
+ if (s.s != 0) {
+ return *p;
+ }
+ }
+
+ 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; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+ 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
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7312221>
+//
+// Test that Objective-C instance variables aren't prematurely pruned
+// from the analysis state.
+//===----------------------------------------------------------------------===//
+
+struct rdar_7312221_value { int x; };
+
+@interface RDar7312221
+{
+ struct rdar_7312221_value *y;
+}
+- (void) doSomething_7312221;
+@end
+
+extern struct rdar_7312221_value *rdar_7312221_helper();
+extern int rdar_7312221_helper_2(id o);
+extern void rdar_7312221_helper_3(int z);
+
+@implementation RDar7312221
+- (void) doSomething_7312221 {
+ if (y == 0) {
+ y = rdar_7312221_helper();
+ if (y != 0) {
+ y->x = rdar_7312221_helper_2(self);
+ // The following use of 'y->x' previously triggered a null dereference, as the value of 'y'
+ // before 'y = rdar_7312221_helper()' would be used.
+ rdar_7312221_helper_3(y->x); // no-warning
+ }
+ }
+}
+@end
+
+struct rdar_7312221_container {
+ struct rdar_7312221_value *y;
+};
+
+extern int rdar_7312221_helper_4(struct rdar_7312221_container *s);
+
+// This test case essentially matches the one in [RDar7312221 doSomething_7312221].
+void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) {
+ if (Self->y == 0) {
+ Self->y = rdar_7312221_helper();
+ if (Self->y != 0) {
+ Self->y->x = rdar_7312221_helper_4(Self);
+ rdar_7312221_helper_3(Self->y->x); // no-warning
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7332673> - Just more tests cases for regions
+//===----------------------------------------------------------------------===//
+
+void rdar_7332673_test1() {
+ char value[1];
+ if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}}
+}
+int rdar_7332673_test2_aux(char *x);
+void rdar_7332673_test2() {
+ char *value;
+ if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7347252>: Because of a bug in
+// RegionStoreManager::RemoveDeadBindings(), the symbol for s->session->p
+// would incorrectly be pruned from the state after the call to
+// rdar7347252_malloc1(), and would incorrectly result in a warning about
+// passing a null pointer to rdar7347252_memcpy().
+//===----------------------------------------------------------------------===//
+
+struct rdar7347252_AA { char *p;};
+typedef struct {
+ struct rdar7347252_AA *session;
+ int t;
+ char *q;
+} rdar7347252_SSL1;
+
+int rdar7347252_f(rdar7347252_SSL1 *s);
+char *rdar7347252_malloc1(int);
+char *rdar7347252_memcpy1(char *d, char *s, int n) __attribute__((nonnull (1,2)));
+
+int rdar7347252(rdar7347252_SSL1 *s) {
+ rdar7347252_f(s); // the SymbolicRegion of 's' is set a default binding of conjured symbol
+ if (s->session->p == ((void*)0)) {
+ if ((s->session->p = rdar7347252_malloc1(10)) == ((void*)0)) {
+ return 0;
+ }
+ rdar7347252_memcpy1(s->session->p, "aa", 2); // no-warning
+ }
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// PR 5316 - "crash when accessing field of lazy compound value"
+// Previously this caused a crash at the MemberExpr '.chr' when loading
+// a field value from a LazyCompoundVal
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int pr5316_wint_t;
+typedef pr5316_wint_t pr5316_REFRESH_CHAR;
+typedef struct {
+ pr5316_REFRESH_CHAR chr;
+}
+pr5316_REFRESH_ELEMENT;
+static void pr5316(pr5316_REFRESH_ELEMENT *dst, const pr5316_REFRESH_ELEMENT *src) {
+ while ((*dst++ = *src++).chr != L'\0') ;
+}
+
+//===----------------------------------------------------------------------===//
+// Exercise creating ElementRegion with symbolic super region.
+//===----------------------------------------------------------------------===//
+void element_region_with_symbolic_superregion(int* p) {
+ int *x;
+ int a;
+ if (p[0] == 1)
+ x = &a;
+ if (p[0] == 1)
+ (void)*x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Test returning an out-of-bounds pointer (CWE-466)
+//===----------------------------------------------------------------------===//
+
+static int test_cwe466_return_outofbounds_pointer_a[10];
+int *test_cwe466_return_outofbounds_pointer() {
+ int *p = test_cwe466_return_outofbounds_pointer_a+10;
+ return p; // expected-warning{{Returned pointer value points outside the original object}}
+}
+
+//===----------------------------------------------------------------------===//
+// PR 3135 - Test case that shows that a variable may get invalidated when its
+// address is included in a structure that is passed-by-value to an unknown function.
+//===----------------------------------------------------------------------===//
+
+typedef struct { int *a; } pr3135_structure;
+int pr3135_bar(pr3135_structure *x);
+int pr3135() {
+ int x;
+ pr3135_structure y = { &x };
+ // the call to pr3135_bar may initialize x
+ if (pr3135_bar(&y) && x) // no-warning
+ return 1;
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7403269> - Test that we handle compound initializers with
+// partially unspecified array values. Previously this caused a crash.
+//===----------------------------------------------------------------------===//
+
+typedef struct RDar7403269 {
+ unsigned x[10];
+ unsigned y;
+} RDar7403269;
+
+void rdar7403269() {
+ RDar7403269 z = { .y = 0 };
+ if (z.x[4] == 0)
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+
+typedef struct RDar7403269_b {
+ struct zorg { int w; int k; } x[10];
+ unsigned y;
+} RDar7403269_b;
+
+void rdar7403269_b() {
+ RDar7403269_b z = { .y = 0 };
+ if (z.x[5].w == 0)
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+}
+
+void rdar7403269_b_pos() {
+ RDar7403269_b z = { .y = 0 };
+ if (z.x[5].w == 1)
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+}
+
+
+//===----------------------------------------------------------------------===//
+// Test that incrementing a non-null pointer results in a non-null pointer.
+// (<rdar://problem/7191542>)
+//===----------------------------------------------------------------------===//
+
+void test_increment_nonnull_rdar_7191542(const char *path) {
+ const char *alf = 0;
+
+ for (;;) {
+ // When using basic-store, we get a null dereference here because we lose information
+ // about path after the pointer increment.
+ char c = *path++; // no-warning
+ if (c == 'a') {
+ alf = path;
+ }
+
+ if (alf)
+ return;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Test that the store (implicitly) tracks values for doubles/floats that are
+// uninitialized (<rdar://problem/6811085>)
+//===----------------------------------------------------------------------===//
+
+double rdar_6811085(void) {
+ double u;
+ return u + 10; // expected-warning{{The left operand of '+' is a garbage value}}
+}
+
+//===----------------------------------------------------------------------===//
+// Path-sensitive tests for blocks.
+//===----------------------------------------------------------------------===//
+
+void indirect_block_call(void (^f)());
+
+int blocks_1(int *p, int z) {
+ __block int *q = 0;
+ void (^bar)() = ^{ q = p; };
+
+ if (z == 1) {
+ // The call to 'bar' might cause 'q' to be invalidated.
+ bar();
+ *q = 0x1; // no-warning
+ }
+ else if (z == 2) {
+ // The function 'indirect_block_call' might invoke bar, thus causing
+ // 'q' to possibly be invalidated.
+ indirect_block_call(bar);
+ *q = 0x1; // no-warning
+ }
+ else {
+ *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+ }
+ return z;
+}
+
+int blocks_2(int *p, int z) {
+ int *q = 0;
+ void (^bar)(int **) = ^(int **r){ *r = p; };
+
+ if (z) {
+ // The call to 'bar' might cause 'q' to be invalidated.
+ bar(&q);
+ *q = 0x1; // no-warning
+ }
+ else {
+ *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+ }
+ return z;
+}
+
+// Test that the value of 'x' is considered invalidated after the block
+// is passed as an argument to the message expression.
+typedef void (^RDar7582031CB)(void);
+@interface RDar7582031
+- rdar7582031:RDar7582031CB;
+- rdar7582031_b:RDar7582031CB;
+@end
+
+// Test with one block.
+unsigned rdar7582031(RDar7582031 *o) {
+ __block unsigned x;
+ [o rdar7582031:^{ x = 1; }];
+ return x; // no-warning
+}
+
+// Test with two blocks.
+unsigned long rdar7582031_b(RDar7582031 *o) {
+ __block unsigned y;
+ __block unsigned long x;
+ [o rdar7582031:^{ y = 1; }];
+ [o rdar7582031_b:^{ x = 1LL; }];
+ return x + (unsigned long) y; // no-warning
+}
+
+// Show we get an error when 'o' is null because the message
+// expression has no effect.
+unsigned long rdar7582031_b2(RDar7582031 *o) {
+ __block unsigned y;
+ __block unsigned long x;
+ if (o)
+ return 1;
+ [o rdar7582031:^{ y = 1; }];
+ [o rdar7582031_b:^{ x = 1LL; }];
+ return x + (unsigned long) y; // expected-warning{{The left operand of '+' is a garbage value}}
+}
+
+// Show that we handle static variables also getting invalidated.
+void rdar7582031_aux(void (^)(void));
+RDar7582031 *rdar7582031_aux_2();
+
+unsigned rdar7582031_static() {
+ static RDar7582031 *o = 0;
+ rdar7582031_aux(^{ o = rdar7582031_aux_2(); });
+
+ __block unsigned x;
+ [o rdar7582031:^{ x = 1; }];
+ return x; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7462324> - Test that variables passed using __blocks
+// are not treated as being uninitialized.
+//===----------------------------------------------------------------------===//
+
+typedef void (^RDar_7462324_Callback)(id obj);
+
+@interface RDar7462324
+- (void) foo:(id)target;
+- (void) foo_positive:(id)target;
+
+@end
+
+@implementation RDar7462324
+- (void) foo:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ if (object) {
+ builder(self); // no-warning
+ }
+ };
+ builder(target);
+}
+- (void) foo_positive:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ id x;
+ if (object) {
+ builder(x); // expected-warning{{Pass-by-value argument in function call is undefined}}
+ }
+ };
+ builder(target);
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7468209> - Scanning for live variables within a block should
+// not crash on variables passed by reference via __block.
+//===----------------------------------------------------------------------===//
+
+int rdar7468209_aux();
+void rdar7468209_aux_2();
+
+void rdar7468209() {
+ __block int x = 0;
+ ^{
+ x = rdar7468209_aux();
+ // We need a second statement so that 'x' would be removed from the store if it wasn't
+ // passed by reference.
+ rdar7468209_aux_2();
+ }();
+}
+
+//===----------------------------------------------------------------------===//
+// PR 5857 - Test loading an integer from a byte array that has also been
+// reinterpreted to be loaded as a field.
+//===----------------------------------------------------------------------===//
+
+typedef struct { int x; } TestFieldLoad;
+int pr5857(char *src) {
+ TestFieldLoad *tfl = (TestFieldLoad *) (intptr_t) src;
+ int y = tfl->x;
+ long long *z = (long long *) (intptr_t) src;
+ long long w = 0;
+ int n = 0;
+ for (n = 0; n < y; ++n) {
+ // Previously we crashed analyzing this statement.
+ w = *z++;
+ }
+ return 1;
+}
+
+//===----------------------------------------------------------------------===//
+// PR 4358 - Without field-sensitivity, this code previously triggered
+// a false positive that 'uninit' could be uninitialized at the call
+// to pr4358_aux().
+//===----------------------------------------------------------------------===//
+
+struct pr4358 {
+ int bar;
+ int baz;
+};
+void pr4358_aux(int x);
+void pr4358(struct pr4358 *pnt) {
+ int uninit;
+ if (pnt->bar < 3) {
+ uninit = 1;
+ } else if (pnt->baz > 2) {
+ uninit = 3;
+ } else if (pnt->baz <= 2) {
+ uninit = 2;
+ }
+ pr4358_aux(uninit); // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7526777>
+// Test handling fields of values returned from function calls or
+// message expressions.
+//===----------------------------------------------------------------------===//
+
+typedef struct testReturn_rdar_7526777 {
+ int x;
+ int y;
+} testReturn_rdar_7526777;
+
+@interface TestReturnStruct_rdar_7526777
+- (testReturn_rdar_7526777) foo;
+@end
+
+int test_return_struct(TestReturnStruct_rdar_7526777 *x) {
+ return [x foo].x;
+}
+
+testReturn_rdar_7526777 test_return_struct_2_aux_rdar_7526777();
+
+int test_return_struct_2_rdar_7526777() {
+ return test_return_struct_2_aux_rdar_7526777().x;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7527292> Assertion failed: (Op == BinaryOperator::Add ||
+// Op == BinaryOperator::Sub)
+// This test case previously triggered an assertion failure due to a discrepancy
+// been the loaded/stored value in the array
+//===----------------------------------------------------------------------===//
+
+_Bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue );
+
+void rdar_7527292() {
+ static id Cache7527292[32];
+ for (signed long idx = 0;
+ idx < 32;
+ idx++) {
+ id v = Cache7527292[idx];
+ if (v && OSAtomicCompareAndSwapPtrBarrier(v, ((void*)0), (void * volatile *)(Cache7527292 + idx))) {
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7515938> - Handle initialization of incomplete arrays
+// in structures using a compound value. Previously this crashed.
+//===----------------------------------------------------------------------===//
+
+struct rdar_7515938 {
+ int x;
+ int y[];
+};
+
+const struct rdar_7515938 *rdar_7515938() {
+ static const struct rdar_7515938 z = { 0, { 1, 2 } };
+ if (z.y[0] != 1) {
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ }
+ return &z;
+}
+
+struct rdar_7515938_str {
+ int x;
+ char y[];
+};
+
+const struct rdar_7515938_str *rdar_7515938_str() {
+ static const struct rdar_7515938_str z = { 0, "hello" };
+ return &z;
+}
+
+//===----------------------------------------------------------------------===//
+// Assorted test cases from PR 4172.
+//===----------------------------------------------------------------------===//
+
+struct PR4172A_s { int *a; };
+
+void PR4172A_f2(struct PR4172A_s *p);
+
+int PR4172A_f1(void) {
+ struct PR4172A_s m;
+ int b[4];
+ m.a = b;
+ PR4172A_f2(&m);
+ return b[3]; // no-warning
+}
+
+struct PR4172B_s { int *a; };
+
+void PR4172B_f2(struct PR4172B_s *p);
+
+int PR4172B_f1(void) {
+ struct PR4172B_s m;
+ int x;
+ m.a = &x;
+ PR4172B_f2(&m);
+ return x; // no-warning
+}
+
diff --git a/test/Analysis/misc-ps-region-store.mm b/test/Analysis/misc-ps-region-store.mm
new file mode 100644
index 0000000..92addd1
--- /dev/null
+++ b/test/Analysis/misc-ps-region-store.mm
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+
+//===------------------------------------------------------------------------------------------===//
+// This files tests our path-sensitive handling of Objective-c++ files.
+//===------------------------------------------------------------------------------------------===//
+
+// Test basic handling of references.
+char &test1_aux();
+char *test1() {
+ return &test1_aux();
+}
+
+// Test test1_aux() evaluates to char &.
+char test1_as_rvalue() {
+ return test1_aux();
+}
+
+// Test basic handling of references with Objective-C classes.
+@interface Test1
+- (char&) foo;
+@end
+
+char* Test1_harness(Test1 *p) {
+ return &[p foo];
+}
+
+char Test1_harness_b(Test1 *p) {
+ return [p foo];
+}
+
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
new file mode 100644
index 0000000..fa05f6f
--- /dev/null
+++ b/test/Analysis/misc-ps.m
@@ -0,0 +1,935 @@
+// NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued.
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code %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, 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;
++ (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,...;
+@end
+extern NSString * const NSConnectionReplyMode;
+typedef float CGFloat;
+typedef struct _NSPoint {
+ CGFloat x;
+ CGFloat y;
+} NSPoint;
+typedef struct _NSSize {
+ CGFloat width;
+ CGFloat height;
+} NSSize;
+typedef struct _NSRect {
+ NSPoint origin;
+ NSSize size;
+} NSRect;
+
+// Reduced test case from crash in <rdar://problem/6253157>
+@interface A @end
+@implementation A
+- (void)foo:(void (^)(NSObject *x))block {
+ if (!((block != ((void *)0)))) {}
+}
+@end
+
+// Reduced test case from crash in PR 2796;
+// http://llvm.org/bugs/show_bug.cgi?id=2796
+
+unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); }
+
+// Improvement to path-sensitivity involving compound assignments.
+// Addresses false positive in <rdar://problem/6268365>
+//
+
+unsigned r6268365Aux();
+
+void r6268365() {
+ unsigned x = 0;
+ x &= r6268365Aux();
+ unsigned j = 0;
+
+ if (x == 0) ++j;
+ if (x == 0) x = x / j; // no-warning
+}
+
+void divzeroassume(unsigned x, unsigned j) {
+ x /= j;
+ if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
+ if (j == 0) x /= j; // no static-analyzer warning
+ if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
+}
+
+void divzeroassumeB(unsigned x, unsigned j) {
+ x = x / j;
+ if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
+ if (j == 0) x /= j; // no static-analyzer warning
+ if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
+}
+
+// InitListExpr processing
+
+typedef float __m128 __attribute__((__vector_size__(16), __may_alias__));
+__m128 return128() {
+ // This compound literal has a Vector type. We currently just
+ // return UnknownVal.
+ return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f };
+}
+
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
+typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
+__m128i vec128i(long long __q1, long long __q0) {
+ // This compound literal returns true for both isVectorType() and
+ // isIntegerType().
+ return __extension__ (__m128i)(__v2di){ __q0, __q1 };
+}
+
+// Zero-sized VLAs.
+void check_zero_sized_VLA(int x) {
+ if (x)
+ return;
+
+ int vla[x]; // expected-warning{{Declared variable-length array (VLA) has zero size}}
+}
+
+void check_uninit_sized_VLA() {
+ int x;
+ int vla[x]; // expected-warning{{Declared variable-length array (VLA) uses a garbage value as its size}}
+}
+
+// sizeof(void)
+// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211
+void handle_sizeof_void(unsigned flag) {
+ int* p = 0;
+
+ if (flag) {
+ if (sizeof(void) == 1)
+ return;
+ // Infeasible.
+ *p = 1; // no-warning
+ }
+
+ void* q;
+
+ if (!flag) {
+ if (sizeof(*q) == 1)
+ return;
+ // Infeasibe.
+ *p = 1; // no-warning
+ }
+
+ // Infeasible.
+ *p = 1; // no-warning
+}
+
+// check deference of undefined values
+void check_deref_undef(void) {
+ int *p;
+ *p = 0xDEADBEEF; // expected-warning{{Dereference of undefined pointer value}}
+}
+
+// PR 3422
+void pr3422_helper(char *p);
+void pr3422() {
+ char buf[100];
+ char *q = &buf[10];
+ pr3422_helper(&q[1]);
+}
+
+// PR 3543 (handle empty statement expressions)
+void pr_3543(void) {
+ ({});
+}
+
+// <rdar://problem/6611677>
+// This test case test the use of a vector type within an array subscript
+// expression.
+typedef long long __a64vector __attribute__((__vector_size__(8)));
+typedef long long __a128vector __attribute__((__vector_size__(16)));
+static inline __a64vector __attribute__((__always_inline__, __nodebug__))
+my_test_mm_movepi64_pi64(__a128vector a) {
+ return (__a64vector)a[0];
+}
+
+// Test basic tracking of ivars associated with 'self'.
+@interface SelfIvarTest : NSObject {
+ int flag;
+}
+- (void)test_self_tracking;
+@end
+
+@implementation SelfIvarTest
+- (void)test_self_tracking {
+ char *p = 0;
+ char c;
+
+ if (flag)
+ p = "hello";
+
+ if (flag)
+ c = *p; // no-warning
+}
+@end
+
+// PR 3770
+char pr3770(int x) {
+ int y = x & 0x2;
+ char *p = 0;
+ if (y == 1)
+ p = "hello";
+
+ if (y == 1)
+ return p[0]; // no-warning
+
+ return 'a';
+}
+
+// PR 3772
+// - We just want to test that this doesn't crash the analyzer.
+typedef struct st ST;
+struct st { char *name; };
+extern ST *Cur_Pu;
+
+void pr3772(void)
+{
+ static ST *last_Cur_Pu;
+ if (last_Cur_Pu == Cur_Pu) {
+ return;
+ }
+}
+
+// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups.
+void pr3780(int sz) { typedef double MAT[sz][sz]; }
+
+// <rdar://problem/6695527> - Test that we don't symbolicate doubles before
+// we are ready to do something with them.
+int rdar6695527(double x) {
+ if (!x) { return 0; }
+ return 1;
+}
+
+// <rdar://problem/6708148> - Test that we properly invalidate structs
+// passed-by-reference to a function.
+void pr6708148_invalidate(NSRect *x);
+void pr6708148_use(NSRect x);
+void pr6708148_test(void) {
+ NSRect x;
+ pr6708148_invalidate(&x);
+ pr6708148_use(x); // no-warning
+}
+
+// Handle both kinds of noreturn attributes for pruning paths.
+void rdar_6777003_noret() __attribute__((noreturn));
+void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
+
+void rdar_6777003(int x) {
+ int *p = 0;
+
+ if (x == 1) {
+ rdar_6777003_noret();
+ *p = 1; // no-warning;
+ }
+
+ if (x == 2) {
+ rdar_6777003_analyzer_noret();
+ *p = 1; // no-warning;
+ }
+
+ *p = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// For pointer arithmetic, --/++ should be treated as preserving non-nullness,
+// regardless of how well the underlying StoreManager reasons about pointer
+// arithmetic.
+// <rdar://problem/6777209>
+void rdar_6777209(char *p) {
+ if (p == 0)
+ return;
+
+ ++p;
+
+ // This branch should always be infeasible.
+ if (p == 0)
+ *p = 'c'; // no-warning
+}
+
+// PR 4033. A symbolic 'void *' pointer can be used as the address for a
+// computed goto.
+typedef void *Opcode;
+Opcode pr_4033_getOpcode();
+void pr_4033(void) {
+next_opcode:
+ {
+ Opcode op = pr_4033_getOpcode();
+ if (op) goto *op;
+ }
+}
+
+// Test invalidating pointers-to-pointers with slightly different types. This
+// example came from a recent false positive due to a regression where the
+// branch condition was falsely reported as being uninitialized.
+void invalidate_by_ref(char **x);
+int test_invalidate_by_ref() {
+ unsigned short y;
+ invalidate_by_ref((char**) &y);
+ if (y) // no-warning
+ return 1;
+ return 0;
+}
+
+// Test for <rdar://problem/7027684>. This just tests that the CFG is
+// constructed correctly. Previously, the successor block of the entrance
+// was the block containing the merge for '?', which would trigger an
+// assertion failure.
+int rdar_7027684_aux();
+int rdar_7027684_aux_2() __attribute__((noreturn));
+void rdar_7027684(int x, int y) {
+ {}; // this empty compound statement is critical.
+ (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}}
+}
+
+int OSAtomicCompareAndSwap32Barrier();
+
+// 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;
+}
+
+int ivar_getOffset();
+
+// 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_symbol_fold_1(signed char x) {
+ while (1) {
+ if (x == ((signed char) 0)) {}
+ }
+}
+
+// This previously caused a crash because it triggered an assertion in APSInt.
+void test_symbol_fold_2(unsigned int * p, unsigned int n,
+ const unsigned int * grumpkin, unsigned int dn) {
+ unsigned int i;
+ unsigned int tempsub[8];
+ unsigned int *solgrumpkin = tempsub + n;
+ for (i = 0; i < n; i++)
+ solgrumpkin[i] = (i < dn) ? ~grumpkin[i] : 0xFFFFFFFF;
+ for (i <<= 5; i < (n << 5); i++) {}
+}
+
+// This previously caused a crash because it triggered an assertion in APSInt.
+// 'x' would evaluate to a 8-bit constant (because of the return value of
+// test_symbol_fold_3_aux()) which would not get properly promoted to an
+// integer.
+char test_symbol_fold_3_aux(void);
+unsigned test_symbol_fold_3(void) {
+ unsigned x = test_symbol_fold_3_aux();
+ if (x == 54)
+ return (x << 8) | 0x5;
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Tests for the warning of casting a non-struct type to a struct type
+//===----------------------------------------------------------------------===//
+
+typedef struct {unsigned int v;} NSSwappedFloat;
+
+NSSwappedFloat test_cast_nonstruct_to_struct(float x) {
+ struct hodor {
+ float number;
+ NSSwappedFloat sf;
+ };
+ return ((struct hodor *)&x)->sf; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
+}
+
+NSSwappedFloat test_cast_nonstruct_to_union(float x) {
+ union bran {
+ float number;
+ NSSwappedFloat sf;
+ };
+ return ((union bran *)&x)->sf; // no-warning
+}
+
+void test_undefined_array_subscript() {
+ int i, a[10];
+ int *p = &a[i]; // expected-warning{{Array subscript is undefined}}
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// Test using an uninitialized value as a branch condition.
+//===----------------------------------------------------------------------===//
+
+int test_uninit_branch(void) {
+ int x;
+ if (x) // expected-warning{{Branch condition evaluates to a garbage value}}
+ return 1;
+ return 0;
+}
+
+int test_uninit_branch_b(void) {
+ int x;
+ return x ? 1 : 0; // expected-warning{{Branch condition evaluates to a garbage value}}
+}
+
+int test_uninit_branch_c(void) {
+ int x;
+ if ((short)x) // expected-warning{{Branch condition evaluates to a garbage value}}
+ return 1;
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Test passing an undefined value in a message or function call.
+//===----------------------------------------------------------------------===//
+
+void test_bad_call_aux(int x);
+void test_bad_call(void) {
+ int y;
+ test_bad_call_aux(y); // expected-warning{{Pass-by-value argument in function call is undefined}}
+}
+
+@interface TestBadArg {}
+- (void) testBadArg:(int) x;
+@end
+
+void test_bad_msg(TestBadArg *p) {
+ int y;
+ [p testBadArg:y]; // expected-warning{{Pass-by-value argument in message expression is undefined}}
+}
+
+//===----------------------------------------------------------------------===//
+// PR 6033 - Test emitting the correct output in a warning where we use '%'
+// with operands that are undefined.
+//===----------------------------------------------------------------------===//
+
+int pr6033(int x) {
+ int y;
+ return x % y; // expected-warning{{The right operand of '%' is a garbage value}}
+}
+
+struct trie {
+ struct trie* next;
+};
+
+struct kwset {
+ struct trie *trie;
+ unsigned char delta[10];
+ struct trie* next[10];
+ int d;
+};
+
+typedef struct trie trie_t;
+typedef struct kwset kwset_t;
+
+void f(kwset_t *kws, char const *p, char const *q) {
+ struct trie const *trie;
+ struct trie * const *next = kws->next;
+ register unsigned char c;
+ register char const *end = p;
+ register char const *lim = q;
+ register int d = 1;
+ register unsigned char const *delta = kws->delta;
+
+ d = delta[c = (end+=d)[-1]]; // no-warning
+ trie = next[c];
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7593875> When handling sizeof(VLA) it leads to a hole in
+// the ExplodedGraph (causing a false positive)
+//===----------------------------------------------------------------------===//
+
+int rdar_7593875_aux(int x);
+int rdar_7593875(int n) {
+ int z[n > 10 ? 10 : n]; // VLA.
+ int v;
+ v = rdar_7593875_aux(sizeof(z));
+ // Previously we got a false positive about 'v' being uninitialized.
+ return v; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Handle casts from symbolic regions (packaged as integers) to doubles.
+// Previously this caused an assertion failure.
+//===----------------------------------------------------------------------===//
+
+void *foo_rev95119();
+void baz_rev95119(double x);
+void bar_rev95119() {
+ // foo_rev95119() returns a symbolic pointer. It is then
+ // cast to an int which is then cast to a double.
+ int value = (int) foo_rev95119();
+ baz_rev95119((double)value);
+}
+
+//===----------------------------------------------------------------------===//
+// Handle loading a symbolic pointer from a symbolic region that was
+// invalidated by a call to an unknown function.
+//===----------------------------------------------------------------------===//
+
+void bar_rev95192(int **x);
+void foo_rev95192(int **x) {
+ *x = 0;
+ bar_rev95192(x);
+ // Not a null dereference.
+ **x = 1; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// Handle casts of a function to a function pointer with a different return
+// value. We don't yet emit an error for such cases, but we now we at least
+// don't crash when the return value gets interpreted in a way that
+// violates our invariants.
+//===----------------------------------------------------------------------===//
+
+void *foo_rev95267();
+int bar_rev95267() {
+ char (*Callback_rev95267)(void) = (char (*)(void)) foo_rev95267;
+ if ((*Callback_rev95267)() == (char) 0)
+ return 1;
+ return 0;
+}
+
+// Same as previous case, but handle casts to 'void'.
+int bar_rev95274() {
+ void (*Callback_rev95274)(void) = (void (*)(void)) foo_rev95267;
+ (*Callback_rev95274)();
+ return 0;
+}
+
+void rdar7582031_test_static_init_zero() {
+ static unsigned x;
+ if (x == 0)
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF;
+}
+void rdar7582031_test_static_init_zero_b() {
+ static void* x;
+ if (x == 0)
+ return;
+ int *p = 0;
+ *p = 0xDEADBEEF;
+}
+
+//===----------------------------------------------------------------------===//
+// Test handling of parameters that are structs that contain floats and //
+// nested fields. //
+//===----------------------------------------------------------------------===//
+
+struct s_rev95547_nested { float x, y; };
+struct s_rev95547 {
+ struct s_rev95547_nested z1;
+ struct s_rev95547_nested z2;
+};
+float foo_rev95547(struct s_rev95547 w) {
+ return w.z1.x + 20.0; // no-warning
+}
+void foo_rev95547_b(struct s_rev95547 w) {
+ struct s_rev95547 w2 = w;
+ w2.z1.x += 20.0; // no-warning
+}
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
new file mode 100644
index 0000000..5722a04
--- /dev/null
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s 2>&1 | FileCheck -check-prefix=darwin8 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin8 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s 2>&1 | FileCheck -check-prefix=darwin9 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin9 %s
+
+@interface MyClass {}
+- (void *)voidPtrM;
+- (int)intM;
+- (long long)longlongM;
+- (double)doubleM;
+- (long double)longDoubleM;
+- (void)voidM;
+@end
+@implementation MyClass
+- (void *)voidPtrM { return (void *)0; }
+- (int)intM { return 0; }
+- (long long)longlongM { return 0; }
+- (double)doubleM { return 0.0; }
+- (long double)longDoubleM { return 0.0; }
+- (void)voidM {}
+@end
+
+void createFoo() {
+ MyClass *obj = 0;
+
+ void *v = [obj voidPtrM]; // no-warning
+ int i = [obj intM]; // no-warning
+}
+
+void createFoo2() {
+ MyClass *obj = 0;
+
+ long double ld = [obj longDoubleM]; // expected-warning{{The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage}}
+}
+
+void createFoo3() {
+ MyClass *obj;
+ obj = 0;
+
+ long long ll = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}}
+}
+
+void createFoo4() {
+ MyClass *obj = 0;
+
+ double d = [obj doubleM]; // expected-warning{{The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage}}
+}
+
+void createFoo5() {
+ MyClass *obj = @"";
+
+ double d = [obj doubleM]; // no-warning
+}
+
+void handleNilPruneLoop(MyClass *obj) {
+ if (!!obj)
+ return;
+
+ // Test if [obj intM] evaluates to 0, thus pruning the entire loop.
+ for (int i = 0; i < [obj intM]; i++) {
+ long long j = [obj longlongM]; // no-warning
+ }
+
+ long long j = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}}
+}
+
+int handleVoidInComma() {
+ MyClass *obj = 0;
+ return [obj voidM], 0;
+}
+
+int marker(void) { // control reaches end of non-void function
+}
+
+// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
+// CHECK-darwin8: control reaches end of non-void function
+// CHECK-darwin8: 5 diagnostics generated
+// CHECK-darwin9: control reaches end of non-void function
+// CHECK-darwin9: 1 diagnostic generated
diff --git a/test/Analysis/no-exit-cfg.c b/test/Analysis/no-exit-cfg.c
new file mode 100644
index 0000000..659f675
--- /dev/null
+++ b/test/Analysis/no-exit-cfg.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// This is a test case for the issue reported in PR 2819:
+// http://llvm.org/bugs/show_bug.cgi?id=2819
+// The flow-sensitive dataflow solver should work even when no block in
+// the CFG reaches the exit block.
+
+int g(int x);
+void h(int x);
+
+int f(int x)
+{
+out_err:
+ if (g(x)) {
+ h(x);
+ }
+ goto out_err;
+}
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
new file mode 100644
index 0000000..f9ac589
--- /dev/null
+++ b/test/Analysis/no-outofbounds.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyzer-check-objc-mem -analyze -analyzer-experimental-internal-checks -analyzer-store=region -verify %s
+// XFAIL: *
+
+//===----------------------------------------------------------------------===//
+// 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-region.c b/test/Analysis/null-deref-ps-region.c
new file mode 100644
index 0000000..0199d20
--- /dev/null
+++ b/test/Analysis/null-deref-ps-region.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+
+// The store for 'a[1]' should not be removed mistakenly. SymbolicRegions may
+// also be live roots.
+void f14(int *a) {
+ int i;
+ a[1] = 1;
+ i = a[1];
+ if (i != 1) {
+ int *p = 0;
+ i = *p; // no-warning
+ }
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
new file mode 100644
index 0000000..704ad33
--- /dev/null
+++ b/test/Analysis/null-deref-ps.c
@@ -0,0 +1,290 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -verify %s -analyzer-constraints=basic -analyzer-store=basic
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -verify %s -analyzer-constraints=range -analyzer-store=basic
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+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;
+ else *p = 0; // expected-warning{{ereference}}
+}
+
+struct foo_struct {
+ int x;
+};
+
+int f2(struct foo_struct* p) {
+
+ if (p)
+ p->x = 1;
+
+ return p->x++; // expected-warning{{Dereference of null pointer}}
+}
+
+int f3(char* x) {
+
+ int i = 2;
+
+ if (x)
+ return x[i - 1];
+
+ return x[i+1]; // expected-warning{{Dereference of null pointer}}
+}
+
+int f3_b(char* x) {
+
+ int i = 2;
+
+ if (x)
+ return x[i - 1];
+
+ return x[i+1]++; // expected-warning{{Dereference of null pointer}}
+}
+
+int f4(int *p) {
+
+ uintptr_t x = (uintptr_t) p;
+
+ if (x)
+ return 1;
+
+ int *q = (int*) x;
+ return *q; // expected-warning{{Dereference of null pointer loaded from variable 'q'}}
+}
+
+int f4_b() {
+ short array[2];
+ uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion initializing}}
+ short *p = x; // expected-warning{{incompatible integer to pointer conversion initializing}}
+
+ // The following branch should be infeasible.
+ if (!(p = &array[0])) {
+ p = 0;
+ *p = 1; // no-warning
+ }
+
+ if (p) {
+ *p = 5; // no-warning
+ p = 0;
+ }
+ else return; // expected-warning {{non-void function 'f4_b' should return a value}}
+
+ *p += 10; // expected-warning{{Dereference of null pointer}}
+ return 0;
+}
+
+
+int f5() {
+
+ char *s = "hello world";
+ return s[0]; // no-warning
+}
+
+int bar(int* p, int q) __attribute__((nonnull));
+
+int f6(int *p) {
+ return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+ : bar(p, 0); // no-warning
+}
+
+int bar2(int* p, int q) __attribute__((nonnull(1)));
+
+int f6b(int *p) {
+ return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+ : bar2(p, 0); // no-warning
+}
+
+int bar3(int*p, int q, int *r) __attribute__((nonnull(1,3)));
+
+int f6c(int *p, int *q) {
+ return !p ? bar3(q, 2, p) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+ : 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) {
+
+ int* p = 0;
+
+ if (0 == x)
+ p = qux();
+
+ if (0 == x)
+ *p = 1; // no-warning
+
+ return x;
+}
+
+int* f7b(int *x) {
+
+ int* p = 0;
+
+ if (((void*)0) == x)
+ p = qux();
+
+ if (((void*)0) == x)
+ *p = 1; // no-warning
+
+ return x;
+}
+
+int* f7c(int *x) {
+
+ int* p = 0;
+
+ if (((void*)0) == x)
+ p = qux();
+
+ if (((void*)0) != x)
+ return x;
+
+ // If we reach here then 'p' is not null.
+ *p = 1; // no-warning
+ return x;
+}
+
+int* f7c2(int *x) {
+
+ int* p = 0;
+
+ if (((void*)0) == x)
+ p = qux();
+
+ if (((void*)0) == x)
+ return x;
+
+ *p = 1; // expected-warning{{null}}
+ return x;
+}
+
+
+void f8(int *p, int *q) {
+ if (!p)
+ if (p)
+ *p = 1; // no-warning
+
+ if (q)
+ if (!q)
+ *q = 1; // no-warning
+}
+
+int* qux();
+
+int f9(unsigned len) {
+ assert (len != 0);
+ int *p = 0;
+ unsigned i;
+
+ for (i = 0; i < len; ++i)
+ p = qux(i);
+
+ return *p++; // no-warning
+}
+
+int f9b(unsigned len) {
+ assert (len > 0); // note use of '>'
+ int *p = 0;
+ unsigned i;
+
+ for (i = 0; i < len; ++i)
+ p = qux(i);
+
+ return *p++; // no-warning
+}
+
+int* f10(int* p, signed char x, int y) {
+ // This line tests symbolication with compound assignments where the
+ // LHS and RHS have different bitwidths. The new symbolic value
+ // for 'x' should have a bitwidth of 8.
+ x &= y;
+
+ // This tests that our symbolication worked, and that we correctly test
+ // x against 0 (with the same bitwidth).
+ if (!x) {
+ if (!p) return; // expected-warning {{non-void function 'f10' should return a value}}
+ *p = 10;
+ }
+ else p = 0;
+
+ if (!x)
+ *p = 5; // no-warning
+
+ return p;
+}
+
+// Test case from <rdar://problem/6407949>
+void f11(unsigned i) {
+ int *x = 0;
+ if (i >= 0) {
+ // always true
+ } else {
+ *x = 42; // no-warning
+ }
+}
+
+void f11b(unsigned i) {
+ int *x = 0;
+ if (i <= ~(unsigned)0) {
+ // always true
+ } else {
+ *x = 42; // no-warning
+ }
+}
+
+// Test case for switch statements with weird case arms.
+typedef int BOOL, *PBOOL, *LPBOOL;
+typedef long LONG_PTR, *PLONG_PTR;
+typedef unsigned long ULONG_PTR, *PULONG_PTR;
+typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
+typedef LONG_PTR LRESULT;
+typedef struct _F12ITEM *HF12ITEM;
+
+void f12(HF12ITEM i, char *q) {
+ char *p = 0;
+ switch ((DWORD_PTR) i) {
+ case 0 ... 10:
+ p = q;
+ break;
+ case (DWORD_PTR) ((HF12ITEM) - 65535):
+ return;
+ default:
+ return;
+ }
+
+ *p = 1; // no-warning
+}
+
+// Test handling of translating between integer "pointers" and back.
+void f13() {
+ int *x = 0;
+ 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
new file mode 100644
index 0000000..45325e9
--- /dev/null
+++ b/test/Analysis/outofbound.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+char f1() {
+ char* s = "abcd";
+ char c = s[4]; // no-warning
+ return s[5] + c; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+void f2() {
+ int *p = malloc(12);
+ p[3] = 4; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
diff --git a/test/Analysis/override-werror.c b/test/Analysis/override-werror.c
new file mode 100644
index 0000000..522b9dc
--- /dev/null
+++ b/test/Analysis/override-werror.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -Werror %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -Werror %s -analyzer-store=region -verify
+
+// This test case illustrates that using '-analyze' overrides the effect of
+// -Werror. This allows basic warnings not to interfere with producing
+// analyzer results.
+
+char* f(int *p) {
+ return p; // expected-warning{{incompatible pointer types returning 'int *', expected 'char *'}}
+}
+
+void g(int *p) {
+ if (!p) *p = 0; // expected-warning{{null}}
+}
+
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
new file mode 100644
index 0000000..f49fef5
--- /dev/null
+++ b/test/Analysis/plist-output.m
@@ -0,0 +1,851 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
+
+void test_null_init(void) {
+ int *p = 0;
+ *p = 0xDEADBEEF;
+}
+
+void test_null_assign(void) {
+ int *p;
+ p = 0;
+ *p = 0xDEADBEEF;
+}
+
+void test_null_assign_transitive(void) {
+ int *p;
+ p = 0;
+ int *q = p;
+ *q = 0xDEADBEEF;
+}
+
+void test_null_cond(int *p) {
+ if (!p) {
+ *p = 0xDEADBEEF;
+ }
+}
+
+void test_null_cond_transitive(int *q) {
+ if (!q) {
+ int *p = q;
+ *p = 0xDEADBEEF;
+ }
+}
+
+void test_null_field(void) {
+ struct s { int *p; } x;
+ x.p = 0;
+ *(x.p) = 0xDEADBEEF;
+}
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK: <key>files</key>
+// CHECK: <array>
+// CHECK: </array>
+// CHECK: <key>diagnostics</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>9</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>9</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Null pointer value stored to 'p'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Null pointer value stored to 'p'</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>15</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>15</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Variable 'q' initialized to a null pointer value</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Variable 'q' initialized to a null pointer value</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'q'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'q'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'q'</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'p'</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>35</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>37</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
new file mode 100644
index 0000000..eb01015
--- /dev/null
+++ b/test/Analysis/pr4209.m
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// This test case was crashing due to how CFRefCount.cpp resolved the
+// ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end @interface NSObject <NSObject> {
+}
+@end typedef float CGFloat;
+typedef struct _NSPoint {
+}
+NSFastEnumerationState;
+@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end @class NSString;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@end @interface NSMutableArray : NSArray - (void)addObject:(id)anObject;
+@end typedef unsigned short unichar;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+- (int)intValue;
+@end @interface NSSimpleCString : NSString {
+}
+@end @interface NSConstantString : NSSimpleCString @end extern void *_NSConstantStringClassReference;
+@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
+@end typedef struct {
+}
+CMProfileLocation;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+@end extern NSString *NSControlTintDidChangeNotification;
+@interface NSActionCell : NSCell {
+}
+@end @class NSArray, NSDocument, NSWindow;
+@interface NSWindowController : NSResponder <NSCoding> {
+}
+@end @class EBayCategoryType, GSEbayCategory, GBSearchRequest;
+@interface GBCategoryChooserPanelController : NSWindowController {
+ GSEbayCategory *rootCategory;
+}
+- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories;
+-(NSString*) categoryID;
+@end @interface GSEbayCategory : NSObject <NSCoding> {
+}
+- (int) categoryID;
+- (GSEbayCategory *) parent;
+- (GSEbayCategory*) subcategoryWithID:(int) inID;
+@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} \
+// expected-warning {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} \
+// expected-warning {{method definition for 'categoryID' not found}}
+ return 0;
+}
+- (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories {
+ GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]];
+
+ if (rootCategory != category) {
+ GSEbayCategory *parent = category;
+ while ((((void*)0) != (parent = [parent parent])) && ([parent categoryID] != 0)) {
+ NSMutableDictionary *treeCategoryDict = [self categoryDictionaryForCategoryID:[parent categoryID] inRootTreeCategories:inRootTreeCategories];
+ if (((void*)0) == treeCategoryDict) {
+ }
+ }
+ }
+}
+@end
diff --git a/test/Analysis/pr_2542_rdar_6793404.m b/test/Analysis/pr_2542_rdar_6793404.m
new file mode 100644
index 0000000..feafe2a
--- /dev/null
+++ b/test/Analysis/pr_2542_rdar_6793404.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -pedantic -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -pedantic -analyzer-store=region -verify %s
+
+// BEGIN delta-debugging reduced header stuff
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSCoder;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end
+@protocol NSCopying
+- (id)copyWithZone:(NSZone *)zone;
+@end
+@protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+typedef double NSTimeInterval;
+enum { NSAnimationEaseInOut, NSAnimationEaseIn, NSAnimationEaseOut, NSAnimationLinear };
+typedef NSUInteger NSAnimationCurve;
+@interface NSAnimation : NSObject <NSCopying, NSCoding> {}
+- (id)initWithDuration:(NSTimeInterval)duration animationCurve:(NSAnimationCurve)animationCurve;
+- (void)startAnimation;
+- (void)setDelegate:(id)delegate;
+@end
+
+// END delta-debugging reduced header stuff
+
+// From NSAnimation Class Reference
+// -(void)startAnimation
+// The receiver retains itself and is then autoreleased at the end
+// of the animation or when it receives stopAnimation.
+
+@interface MyClass { }
+- (void)animationDidEnd:(NSAnimation *)animation;
+@end
+
+@implementation MyClass
+- (void)f1 {
+ // NOTE: The analyzer doesn't really handle this; it just stops tracking
+ // 'animation' when it is sent the message 'setDelegate:'.
+ NSAnimation *animation = [[NSAnimation alloc] // no-warning
+ initWithDuration:1.0
+ animationCurve:NSAnimationEaseInOut];
+
+ [animation setDelegate:self];
+ [animation startAnimation];
+}
+
+- (void)f2 {
+ NSAnimation *animation = [[NSAnimation alloc] // expected-warning{{leak}}
+ initWithDuration:1.0
+ animationCurve:NSAnimationEaseInOut];
+
+ [animation startAnimation];
+}
+
+- (void)animationDidEnd:(NSAnimation *)animation {
+ [animation release];
+}
+@end
diff --git a/test/Analysis/pr_4164.c b/test/Analysis/pr_4164.c
new file mode 100644
index 0000000..e8a410f
--- /dev/null
+++ b/test/Analysis/pr_4164.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+// PR 4164: http://llvm.org/bugs/show_bug.cgi?id=4164
+//
+// Eventually this should be pulled into misc-ps.m. This is in a separate test
+// file for now to play around with the specific issues for BasicStoreManager
+// and StoreManager (i.e., we can make a copy of this file for either
+// StoreManager should one start to fail in the near future).
+//
+// The basic issue is that the VarRegion for 'size' is casted to (char*),
+// resulting in an ElementRegion. 'getsockopt' is an unknown function that
+// takes a void*, which means the ElementRegion should get stripped off.
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_socklen_t;
+typedef __darwin_socklen_t socklen_t;
+int getsockopt(int, int, int, void * restrict, socklen_t * restrict);
+
+int test1() {
+ int s = -1;
+ int size;
+ socklen_t size_len = sizeof(size);
+ if (getsockopt(s, 0xffff, 0x1001, (char *)&size, &size_len) < 0)
+ return -1;
+
+ return size; // no-warning
+}
+
+// Similar case: instead of passing a 'void*', we pass 'char*'. In this
+// case we pass an ElementRegion to the invalidation logic. Since it is
+// an ElementRegion that just layers on top of another typed region and the
+// ElementRegion itself has elements whose type are integral (essentially raw
+// data) we strip off the ElementRegion when doing the invalidation.
+int takes_charptr(char* p);
+int test2() {
+ int size;
+ if (takes_charptr((char*)&size))
+ return -1;
+ return size; // no-warning
+}
+
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
new file mode 100644
index 0000000..f6bd61c
--- /dev/null
+++ b/test/Analysis/ptr-arith.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -triple i686-apple-darwin9 %s
+
+void f1() {
+ int a[10];
+ int *p = a;
+ ++p;
+}
+
+char* foo();
+
+void f2() {
+ char *p = foo();
+ ++p;
+}
+
+// This test case checks if we get the right rvalue type of a TypedViewRegion.
+// The ElementRegion's type depends on the array region's rvalue type. If it was
+// a pointer type, we would get a loc::SymbolVal for '*p'.
+void* memchr();
+static int
+domain_port (const char *domain_b, const char *domain_e,
+ const char **domain_e_ptr)
+{
+ int port = 0;
+
+ const char *p;
+ const char *colon = memchr (domain_b, ':', domain_e - domain_b);
+
+ for (p = colon + 1; p < domain_e ; p++)
+ port = 10 * port + (*p - '0');
+ return port;
+}
+
+void f3() {
+ int x, y;
+ int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
+
+ int a[10];
+ int *p = &a[2];
+ int *q = &a[8];
+ d = q-p; // no-warning
+}
+
+void f4() {
+ int *p;
+ p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
+}
+
+void f5() {
+ int x, y;
+ int *p;
+ p = &x + 1; // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
+
+ int a[10];
+ p = a + 1; // no-warning
+}
+
+// Allow arithmetic on different symbolic regions.
+void f6(int *p, int *q) {
+ int d = q - p; // no-warning
+}
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
new file mode 100644
index 0000000..a2af946
--- /dev/null
+++ b/test/Analysis/rdar-6442306-1.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=basic -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem %s -analyzer-store=region -verify
+
+typedef int bar_return_t;
+typedef struct {
+ unsigned char int_rep;
+} Foo_record_t;
+extern Foo_record_t Foo_record;
+struct QuxSize {};
+typedef struct QuxSize QuxSize;
+typedef struct {
+ Foo_record_t Foo;
+ QuxSize size;
+} __Request__SetPortalSize_t;
+
+double __Foo_READSWAP__double(double*);
+
+static __inline__ bar_return_t
+__Beeble_check__Request__SetPortalSize_t(__attribute__((__unused__)) __Request__SetPortalSize_t *In0P) {
+ if (In0P->Foo.int_rep != Foo_record.int_rep) {
+ do {
+ int __i__, __C__ = (2);
+ for (__i__ = 0;
+ __i__ < __C__;
+ __i__++) do {
+ *(&((double *)(&In0P->size))[__i__]) =
+ __Foo_READSWAP__double(&((double *)(&In0P->size))[__i__]);
+ }
+ while (0);
+ }
+ while (0);
+ }
+ return 0;
+}
diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m
new file mode 100644
index 0000000..dd01810
--- /dev/null
+++ b/test/Analysis/rdar-6540084.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -verify %s
+//
+// This test exercises the live variables analysis (LiveVariables.cpp).
+// The case originally identified a non-termination bug.
+//
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {} @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@class NSArray;
+@class NSMutableArray, NSIndexSet, NSView, NSPredicate, NSString, NSViewAnimation, NSTimer;
+@interface FooBazController : NSObject {}
+@end
+typedef struct {} TazVersion;
+@class TazNode;
+@interface TazGuttenberg : NSObject {} typedef NSUInteger BugsBunnyType; @end
+@interface FooBaz : NSObject {}
+@property (nonatomic) BugsBunnyType matchType;
+@property (nonatomic, retain) NSArray *papyrus; @end
+@implementation FooBazController
+- (NSArray *)excitingStuff:(FooBaz *)options {
+ BugsBunnyType matchType = options.matchType;
+ NSPredicate *isSearchablePredicate = [NSPredicate predicateWithFormat:@"isSearchable == YES"]; // expected-warning{{receiver 'NSPredicate' is a forward class and corresponding}} // expected-warning{{return type defaults to 'id'}}
+ for (TazGuttenberg *Guttenberg in options.papyrus) {
+ NSArray *GuttenbergNodes = [Guttenberg nodes]; // expected-warning{{return type defaults to 'id'}}
+ NSArray *searchableNodes = [GuttenbergNodes filteredArrayUsingPredicate:isSearchablePredicate]; // expected-warning{{return type defaults to 'id'}}
+ for (TazNode *node in searchableNodes) {
+ switch (matchType) {
+ default: break;
+ }
+ }
+ }
+ while (1) {}
+}
+@end
diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c
new file mode 100644
index 0000000..82232c6
--- /dev/null
+++ b/test/Analysis/rdar-6541136-region.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s
+
+struct tea_cheese { unsigned magic; };
+typedef struct tea_cheese kernel_tea_cheese_t;
+extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
+
+// This test case exercises the ElementRegion::getRValueType() logic.
+
+void test1( void ) {
+ kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+ struct load_wine *cmd = (void*) &wonky[1];
+ cmd = cmd;
+ char *p = (void*) &wonky[1];
+ kernel_tea_cheese_t *q = &wonky[1];
+ // 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; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
+
+void test1_b( void ) {
+ kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+ struct load_wine *cmd = (void*) &wonky[1];
+ cmd = cmd;
+ char *p = (void*) &wonky[1];
+ *p = 1; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
+}
diff --git a/test/Analysis/rdar-6541136.c b/test/Analysis/rdar-6541136.c
new file mode 100644
index 0000000..844a936
--- /dev/null
+++ b/test/Analysis/rdar-6541136.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic %s
+
+struct tea_cheese { unsigned magic; };
+typedef struct tea_cheese kernel_tea_cheese_t;
+extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
+
+// This test case exercises the ElementRegion::getRValueType() logic.
+// All it tests is that it does not crash or do anything weird.
+// The out-of-bounds-access on line 19 is caught using the region store variant.
+
+void foo( void )
+{
+ kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+ struct load_wine *cmd = (void*) &wonky[1];
+ cmd = cmd;
+ char *p = (void*) &wonky[1];
+ *p = 1;
+ kernel_tea_cheese_t *q = &wonky[1];
+ kernel_tea_cheese_t r = *q; // no-warning
+}
diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m
new file mode 100644
index 0000000..2aa2229
--- /dev/null
+++ b/test/Analysis/rdar-6562655.m
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region -verify %s
+//
+// This test case mainly checks that the retain/release checker doesn't crash
+// on this file.
+//
+typedef int int32_t;
+typedef signed char BOOL;
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end @interface NSObject <NSObject> {}
+@end extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSResponder : NSObject <NSCoding> {}
+@end @protocol NSAnimatablePropertyContainer - (id)animator;
+@end extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder <NSAnimatablePropertyContainer> {
+}
+@end enum {
+NSNullCellType = 0, NSTextCellType = 1, NSImageCellType = 2 };
+typedef struct __CFlags {
+ unsigned int botnet:3;
+}
+ _CFlags;
+@interface Bar : NSObject <NSCopying, NSCoding> {
+ _CFlags _cFlags;
+@private id _support;
+}
+@end extern NSString *NSControlTintDidChangeNotification;
+typedef NSInteger NSBotnet;
+@interface NSControl : NSView {
+}
+@end @class NSAttributedString, NSFont, NSImage, NSSound;
+typedef int32_t Baz;
+@interface Bar(BarInternal) - (void)_setIsWhite:(BOOL)isWhite;
+@end
+@interface Bar (BarBotnetCompatibility)
+- (NSBotnet)_initialBotnetZorg;
+@end
+typedef struct _NSRunArrayItem {
+ unsigned int botnetIsSet:1;
+} BarAuxFlags;
+@interface BarAuxiliary : NSObject {
+@public
+ NSControl *controlView;
+ BarAuxFlags auxCFlags;
+}
+@end
+@implementation Bar
+static Baz Qux = 0;
+- (id)copyWithZone:(NSZone *)zone { return 0; }
+- (void)encodeWithCoder:(NSCoder *)coder {}
+@end
+@implementation Bar (BarBotnet)
+- (NSBotnet)botnet {
+ if (!(*(BarAuxiliary **)&self->_support)->auxCFlags.botnetIsSet) {
+ _cFlags.botnet = [self _initialBotnetZorg];
+ }
+ while (1) {}
+}
+@end
diff --git a/test/Analysis/rdar-6582778-basic-store.c b/test/Analysis/rdar-6582778-basic-store.c
new file mode 100644
index 0000000..ff32372
--- /dev/null
+++ b/test/Analysis/rdar-6582778-basic-store.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+
+typedef const void * CFTypeRef;
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFDate * CFDateRef;
+
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+void f(void) {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFTypeRef vals[] = { CFDateCreate(0, t) }; // no-warning
+}
+
+CFTypeRef global;
+
+void g(void) {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ global = CFDateCreate(0, t); // no-warning
+}
diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
new file mode 100644
index 0000000..838a98b
--- /dev/null
+++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=basic %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-constraints=basic -analyzer-store=region %s -verify
+
+typedef struct Foo { int x; } Bar;
+
+@interface MyClass {}
+- (Bar)foo;
+@end
+@implementation MyClass
+- (Bar)foo {
+ struct Foo f = { 0 };
+ return f;
+}
+@end
+
+void createFoo() {
+ MyClass *obj = 0;
+ Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}}
+}
+
+void createFoo2() {
+ MyClass *obj = 0;
+ [obj foo]; // no-warning
+ Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}}
+}
+
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
new file mode 100644
index 0000000..bb34713
--- /dev/null
+++ b/test/Analysis/rdar-7168531.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -triple i386-apple-darwin10 -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -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/refcnt_naming.m b/test/Analysis/refcnt_naming.m
new file mode 100644
index 0000000..9defce2
--- /dev/null
+++ b/test/Analysis/refcnt_naming.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+typedef const struct __CFURL * CFURLRef;
+extern CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL);
+typedef signed char BOOL;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {} @end
+@class NSArray, NSString, NSURL;
+
+@interface NamingTest : NSObject {}
+-(NSObject*)photocopy; // read as "photocopy"
+-(NSObject*)photoCopy; // read as "photo Copy"
+-(NSObject*)__blebPRCopy; // read as "bleb PRCopy"
+-(NSObject*)__blebPRcopy; // read as "bleb P Rcopy"
+-(NSObject*)new_theprefixdoescount; // read as "new theprefixdoescount"
+-(NSObject*)newestAwesomeStuff; // read as "newest awesome stuff"
+
+@end
+
+@interface MyClass : NSObject
+{
+ id myObject;
+}
+- (NSURL *)myMethod:(NSString *)inString;
+- (NSURL *)getMethod:(NSString*)inString;
+- (void)addObject:(id)X;
+@end
+
+@implementation MyClass
+
+- (NSURL *)myMethod:(NSString *)inString
+{
+ NSURL *url = (NSURL *)CFURLCreateWithString(0, (CFStringRef)inString, 0); // expected-warning{{leak}}
+ return url;
+}
+
+- (NSURL *)getMethod:(NSString *)inString
+{
+ NSURL *url = (NSURL *)CFURLCreateWithString(0, (CFStringRef)inString, 0);
+ [self addObject:url];
+ return url; // no-warning
+}
+
+void testNames(NamingTest* x) {
+ [x photocopy]; // no-warning
+ [x photoCopy]; // expected-warning{{leak}}
+ [x __blebPRCopy]; // expected-warning{{leak}}
+ [x __blebPRcopy]; // no-warning
+ [x new_theprefixdoescount]; // expected-warning{{leak}}
+ [x newestAwesomeStuff]; // no-warning
+}
+
+
+- (void)addObject:(id)X
+{
+ myObject = X;
+}
+
+@end
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
new file mode 100644
index 0000000..54d7cf5
--- /dev/null
+++ b/test/Analysis/reference.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+void f1() {
+ int const &i = 3;
+ int b = i;
+
+ int *p = 0;
+
+ if (b != 3)
+ *p = 1; // no-warning
+}
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
new file mode 100644
index 0000000..9274cfc
--- /dev/null
+++ b/test/Analysis/region-1.m
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s
+//
+// This test case simply should not crash. It evaluates the logic of not
+// using MemRegion::getRValueType in incorrect places.
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+- (Class)class;
+- (BOOL)isLegOfClass:(Class)aClass;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end @interface NSObject <NSObject> {
+}
+@end @class NSArray;
+@interface NSResponder : NSObject <NSCoding> {
+}
+@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
+@class JabasectItem;
+@protocol EcoClassifier;
+@protocol EcoClassInterfaceCommons <EcoClassifier> @end @protocol EcoImplementation;
+@protocol EcoBehavioredClassifier <EcoClassInterfaceCommons> - (NSArray *) implementations;
+@end enum {
+CK_UNRESTRICTED= 0, CK_READ_ONLY, CK_ADD_ONLY, CK_REMOVE_ONLY };
+@protocol EcoClass <EcoBehavioredClassifier> - (NSArray *) ownedAttributes;
+@end @protocol EcoNamespace;
+@protocol EcoType;
+@protocol EcoClassifier <EcoNamespace,EcoType> - (NSArray *) features;
+@end @protocol EcoComment;
+@protocol EcoElement <NSObject> - (NSArray *) ownedElements;
+@end @protocol EcoDirectedRelationship;
+@protocol EcoNamedElement <EcoElement> - (NSString *) name;
+@end extern NSString *const JabaPathSeparator;
+@protocol EcoNamespace <EcoNamedElement> - (NSArray *) Legs;
+@end enum {
+PDK_IN=0, PDK_INOUT, PDK_OUT, PDK_RETURN };
+@interface EcoElementImp : NSObject <EcoElement, NSCoding> {
+}
+@end @class EcoNamespace;
+@interface EcoNamedElementImp : EcoElementImp <EcoNamedElement>{
+}
+@end @interface EcoNamespaceImp : EcoNamedElementImp <EcoNamespace> {
+}
+@end @class JabaSCDocController, JabaSCDisplaySpecification;
+@interface JabaSCSharedDiagramViewController : NSObject {
+}
+@end extern NSString *const JabaSCsectGraphicNamesectIdentifier;
+@interface EcoClassifierImp : EcoNamespaceImp <EcoClassifier> {
+}
+@end @class EcoOperationImp;
+@interface EcoClassImp : EcoClassifierImp <EcoClass> {
+}
+@end extern NSString *const JabaAddedUMLElements;
+@class JabaSCClass, JabaSCInterface, JabaSCOperation;
+@class DosLegVaseSymbol, DosProtocolSymbol, DosMethodSymbol, DosFileReference;
+@interface HancodeFett : NSObject {
+}
++ (DosLegVaseSymbol *) symbolFromClass: (JabaSCClass *) clz;
+@end enum _JabaSourceLanguage {
+JabaSourceUnknown=0, JabaSourcePrawn, JabaSourceC, JabaSourceCPP, JabaSourceObjectiveC };
+typedef NSUInteger JabaSourceLanguage;
+@protocol JabaSCClassifier <EcoClassInterfaceCommons> - (JabaSourceLanguage)language;
+@end @interface JabaSCClass : EcoClassImp <JabaSCClassifier> {
+}
+@end @class DosGlobalID, DosPQuLC, DosPQuUnLC;
+@protocol XCProxyObjectProtocol - (id) representedObject;
+@end typedef union _Dossymbollocation {
+}
+ DosRecordArrPrl;
+@interface DosIndexEntry : NSObject {
+}
+@end @class DosProjectIndex, DosTextPapyruswiggle, DosDocPapyruswiggle, DosLegVaseSymbol;
+@interface DosSymbol : DosIndexEntry {
+}
+@end @interface DosLegVaseSymbol : DosSymbol {
+}
+@end typedef enum _DosTextRangeType {
+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];
+ id <EcoNamedElement> selectedClassifier = selectedElement;
+ DosSymbol *symbol=((void *)0);
+ if([selectedClassifier isLegOfClass:[JabaSCClass class]]) {
+ symbol = [HancodeFett symbolFromClass:(JabaSCClass *) selectedClassifier];
+ }
+}
+@end
diff --git a/test/Analysis/retain-release-basic-store.m b/test/Analysis/retain-release-basic-store.m
new file mode 100644
index 0000000..751dca0
--- /dev/null
+++ b/test/Analysis/retain-release-basic-store.m
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not including Foundation.h directly makes this test case both svelte and
+// portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long UInt32;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+typedef const struct __CFDictionary * CFDictionaryRef;
+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 };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+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 signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end @interface NSObject <NSObject> {
+}
+@end typedef float CGFloat;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end enum {
+NSObjCNoType = 0, NSObjCVoidType = 'v', NSObjCCharType = 'c', NSObjCShortType = 's', NSObjCLongType = 'l', NSObjCLonglongType = 'q', NSObjCFloatType = 'f', NSObjCDoubleType = 'd', NSObjCBoolType = 'B', NSObjCSelectorType = ':', NSObjCObjectType = '@', NSObjCStructType = '{', NSObjCPointerType = '^', NSObjCStringType = '*', NSObjCArrayType = '[', NSObjCUnionType = '(', NSObjCBitfield = 'b' }
+__attribute__((deprecated));
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+typedef mach_port_t io_object_t;
+typedef io_object_t io_service_t;
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSAppleEventManager : NSObject {
+}
+@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 );
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+// Test to see if we supresss an error when we store the pointer
+// to a struct. This is because the value "escapes" the basic reasoning
+// of basic store.
+
+struct foo {
+ NSDate* f;
+};
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+CFAbsoluteTime f4() {
+ struct foo x;
+
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ [((NSDate*) date) retain];
+ CFRelease(date);
+ CFDateGetAbsoluteTime(date); // no-warning
+ x.f = (NSDate*) date;
+ [((NSDate*) date) release];
+ t = CFDateGetAbsoluteTime(date); // no-warning
+ return t;
+}
+
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
new file mode 100644
index 0000000..8995d5f
--- /dev/null
+++ b/test/Analysis/retain-release-gc-only.m
@@ -0,0 +1,387 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify -fobjc-gc-only -fblocks %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
+
+//===----------------------------------------------------------------------===//
+// Header stuff.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+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;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+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 };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+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 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;
+- (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> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+- (void)release;
+- (id)copy;
+@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;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@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;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+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 @protocol NSAnimatablePropertyContainer - (id)animator;
+@end extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder <NSAnimatablePropertyContainer> {
+}
+@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 NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+@interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+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
+cf) {
+ return cf ? (id)CFMakeCollectable(cf) : ((void*)0);
+}
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+void f1() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+ id x = [(id) A autorelease];
+ CFRelease((CFMutableArrayRef) x);
+}
+
+void f2() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+ id x = [(id) A retain];
+ [x release];
+ [x release];
+}
+
+void f3() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+ CFMakeCollectable(A);
+ CFRetain(A);
+}
+
+void f3b() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+ CFMakeCollectable(A);
+}
+
+
+void f4() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+ NSMakeCollectable(A);
+ CFRetain(A);
+}
+
+void f4b() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+ NSMakeCollectable(A);
+}
+
+void f5() {
+ id x = [NSMakeCollectable(CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks)) autorelease]; // no-warning
+}
+
+void f5b() {
+ id x = [(id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks) autorelease]; // expected-warning{{leak}}
+}
+
+// Test return of non-owned objects in contexts where an owned object
+// is expected.
+@interface TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString;
+- (CFMutableArrayRef)newArray;
+@end
+
+@implementation TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString {
+ NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated}}
+ CFRetain(s);
+ return s;
+}
+- (CFMutableArrayRef)newArray{
+ return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6948053> False positive: object substitution during -init*
+// methods warns about returning +0 when using -fobjc-gc-only
+//===----------------------------------------------------------------------===//
+
+@interface MyClassRdar6948053 : NSObject
+- (id) init;
++ (id) shared;
+@end
+
+@implementation MyClassRdar6948053
++(id) shared {
+ return (id) 0;
+}
+- (id) init
+{
+ Class myClass = [self class];
+ [self release];
+ return [[myClass shared] retain]; // no-warning
+}
+@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}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6250216> Warn against using -[NSAutoreleasePool release] in
+// GC mode
+//===----------------------------------------------------------------------===//
+
+void rdar_6250216(void) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ [pool release]; // expected-warning{{Use -drain instead of -release when using NSAutoreleasePool and garbage collection}}
+}
+
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7407273> Don't crash when analyzing messages sent to blocks
+//===----------------------------------------------------------------------===//
+
+@class RDar7407273;
+typedef void (^RDar7407273Block)(RDar7407273 *operation);
+void rdar7407273(RDar7407273Block b) {
+ [b copy];
+}
+
+//===----------------------------------------------------------------------===//
+// Tests of ownership attributes.
+//===----------------------------------------------------------------------===//
+
+@interface TestOwnershipAttr : NSObject
+- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
+- (NSString*) returnsAnOwnedCFString __attribute__((cf_returns_retained));
+@end
+
+void test_attr_1(TestOwnershipAttr *X) {
+ NSString *str = [X returnsAnOwnedString]; // no-warning
+}
+
+void test_attr_1b(TestOwnershipAttr *X) {
+ NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
+}
+
+@interface MyClassTestCFAttr : NSObject {}
+- (NSDate*) returnsCFRetained __attribute__((cf_returns_retained));
+- (NSDate*) alsoReturnsRetained;
+- (NSDate*) returnsNSRetained __attribute__((ns_returns_retained));
+@end
+
+__attribute__((cf_returns_retained))
+CFDateRef returnsRetainedCFDate() {
+ return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+}
+
+@implementation MyClassTestCFAttr
+- (NSDate*) returnsCFRetained {
+ return (NSDate*) returnsRetainedCFDate(); // No leak.
+}
+
+- (NSDate*) alsoReturnsRetained {
+ return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+
+- (NSDate*) returnsNSRetained {
+ return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
+}
+@end
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
new file mode 100644
index 0000000..111d4b9
--- /dev/null
+++ b/test/Analysis/retain-release-region-store.m
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not including Foundation.h directly makes this test case both svelte and
+// portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long UInt32;
+typedef signed long CFIndex;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+typedef const struct __CFDictionary * CFDictionaryRef;
+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 };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+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 signed char BOOL;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+@end
+typedef float CGFloat;
+typedef double NSTimeInterval;
+@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate;
+@end enum {
+NSObjCNoType = 0, NSObjCVoidType = 'v', NSObjCCharType = 'c', NSObjCShortType = 's', NSObjCLongType = 'l', NSObjCLonglongType = 'q', NSObjCFloatType = 'f', NSObjCDoubleType = 'd', NSObjCBoolType = 'B', NSObjCSelectorType = ':', NSObjCObjectType = '@', NSObjCStructType = '{', NSObjCPointerType = '^', NSObjCStringType = '*', NSObjCArrayType = '[', NSObjCUnionType = '(', NSObjCBitfield = 'b' }
+__attribute__((deprecated));
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+typedef mach_port_t io_object_t;
+typedef io_object_t io_service_t;
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+@interface NSAppleEventManager : NSObject {
+}
+@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 NSNumber : NSObject
+- (id)initWithInt:(int)value;
+@end
+typedef unsigned long NSUInteger;
+@interface NSArray : NSObject
+-(id) initWithObjects:(const id *)objects count:(NSUInteger) cnt;
+@end
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+// Test to see if we *issue* an error when we store the pointer
+// to a struct. This differs from basic store.
+
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+struct foo {
+ NSDate* f;
+};
+
+CFAbsoluteTime f4() {
+ struct foo x;
+
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ [((NSDate*) date) retain];
+ CFRelease(date);
+ CFDateGetAbsoluteTime(date); // no-warning
+ x.f = (NSDate*) date;
+ [((NSDate*) date) release];
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ return t;
+}
+
+// Test that assigning to an self.ivar loses track of an object.
+// This is a temporary hack to reduce false positives.
+@interface Test3 : NSObject {
+ id myObj;
+}
+- (void)test_self_assign_ivar;
+@end
+
+@implementation Test3
+- (void)test_self_assign_ivar {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t); // no-warning
+ myObj = (id) date;
+}
+@end
+
+//===------------------------------------------------------------------------------------------===//
+// <rdar://problem/7257223> (also <rdar://problem/7283470>) - False positive due to not invalidating
+// the reference count of a tracked region that was itself invalidated.
+//===------------------------------------------------------------------------------------------===//
+
+typedef struct __rdar_7257223 { CFDateRef x; } RDar7257223;
+void rdar_7257223_aux(RDar7257223 *p);
+
+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;
+}
+
+void rdar7283470(void) {
+ NSNumber *numbers[] = {
+ [[NSNumber alloc] initWithInt:1], // no-warning
+ [[NSNumber alloc] initWithInt:2], // no-warning
+ [[NSNumber alloc] initWithInt:3], // no-warning
+ [[NSNumber alloc] initWithInt:4], // no-warning
+ [[NSNumber alloc] initWithInt:5] // no-warning
+ };
+
+ for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+ [numbers[i] release];
+}
+
+void rdar7283470_positive(void) {
+ NSNumber *numbers[] = {
+ [[NSNumber alloc] initWithInt:1], // expected-warning{{leak}}
+ [[NSNumber alloc] initWithInt:2], // expected-warning{{leak}}
+ [[NSNumber alloc] initWithInt:3], // expected-warning{{leak}}
+ [[NSNumber alloc] initWithInt:4], // expected-warning{{leak}}
+ [[NSNumber alloc] initWithInt:5] // expected-warning{{leak}}
+ };
+}
+
+void rdar7283470_2(void) {
+ NSNumber *numbers[] = {
+ [[NSNumber alloc] initWithInt:1], // no-warning
+ [[NSNumber alloc] initWithInt:2], // no-warning
+ [[NSNumber alloc] initWithInt:3], // no-warning
+ [[NSNumber alloc] initWithInt:4], // no-warning
+ [[NSNumber alloc] initWithInt:5] // no-warning
+ };
+
+ NSArray *s_numbers =[[NSArray alloc] initWithObjects:&numbers[0] count:sizeof(numbers) / sizeof(numbers[0])];
+
+ for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+ [numbers[i] release];
+
+ [s_numbers release];
+}
+
+void rdar7283470_2_positive(void) {
+ NSNumber *numbers[] = {
+ [[NSNumber alloc] initWithInt:1], // no-warning
+ [[NSNumber alloc] initWithInt:2], // no-warning
+ [[NSNumber alloc] initWithInt:3], // no-warning
+ [[NSNumber alloc] initWithInt:4], // no-warning
+ [[NSNumber alloc] initWithInt:5] // no-warning
+ };
+
+ NSArray *s_numbers =[[NSArray alloc] initWithObjects: &numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; // expected-warning{{leak}}
+
+ for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
+ [numbers[i] release];
+}
+
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
new file mode 100644
index 0000000..1c41d85
--- /dev/null
+++ b/test/Analysis/retain-release.m
@@ -0,0 +1,1307 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=basic -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -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:
+//
+// #include <Cocoa/Cocoa.h>
+// #include <CoreFoundation/CoreFoundation.h>
+// #include <DiskArbitration/DiskArbitration.h>
+// #include <QuartzCore/QuartzCore.h>
+// #include <Quartz/Quartz.h>
+// #include <IOKit/IOKitLib.h>
+//
+// It includes the basic definitions for the test cases below.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+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;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+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 };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+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 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;
+- (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> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (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;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+@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;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+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 @protocol NSAnimatablePropertyContainer - (id)animator;
+@end extern NSString *NSAnimationTriggerOrderIn ;
+@interface NSView : NSResponder <NSAnimatablePropertyContainer> {
+}
+@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 NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+@interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+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
+
+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.
+//===----------------------------------------------------------------------===//
+
+CFAbsoluteTime f1() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ CFRetain(date);
+ CFRelease(date);
+ CFDateGetAbsoluteTime(date); // no-warning
+ CFRelease(date);
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ return t;
+}
+
+CFAbsoluteTime f2() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ [((NSDate*) date) retain];
+ CFRelease(date);
+ CFDateGetAbsoluteTime(date); // no-warning
+ [((NSDate*) date) release];
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ return t;
+}
+
+
+NSDate* global_x;
+
+// Test to see if we supresss an error when we store the pointer
+// to a global.
+
+CFAbsoluteTime f3() {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t);
+ [((NSDate*) date) retain];
+ CFRelease(date);
+ CFDateGetAbsoluteTime(date); // no-warning
+ global_x = (NSDate*) date;
+ [((NSDate*) date) release];
+ t = CFDateGetAbsoluteTime(date); // no-warning
+ return t;
+}
+
+//---------------------------------------------------------------------------
+// Test case 'f4' differs for region store and basic store. See
+// retain-release-region-store.m and retain-release-basic-store.m.
+//---------------------------------------------------------------------------
+
+// Test a leak.
+
+CFAbsoluteTime f5(int x) {
+ CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
+ CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}}
+
+ if (x)
+ CFRelease(date);
+
+ return t;
+}
+
+// Test a leak involving the return.
+
+CFDateRef f6(int x) {
+ CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}}
+ CFRetain(date);
+ return date;
+}
+
+// Test a leak involving an overwrite.
+
+CFDateRef f7() {
+ CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}}
+ CFRetain(date);
+ date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+ return date;
+}
+
+// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and
+// has the word create.
+CFDateRef MyDateCreate();
+
+CFDateRef f8() {
+ CFDateRef date = MyDateCreate(); // expected-warning{{leak}}
+ CFRetain(date);
+ return date;
+}
+
+CFDateRef f9() {
+ CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+ int *p = 0;
+ // When allocations fail, CFDateCreate can return null.
+ if (!date) *p = 1; // expected-warning{{null}}
+ return date;
+}
+
+// Handle DiskArbitration API:
+//
+// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/
+//
+void f10(io_service_t media, DADiskRef d, CFStringRef s) {
+ DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}}
+ if (disk) NSLog(@"ok");
+
+ disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}}
+ if (disk) NSLog(@"ok");
+
+ CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}}
+ if (dict) NSLog(@"ok");
+
+ disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}}
+ if (disk) NSLog(@"ok");
+
+ DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}}
+ kDAReturnSuccess, s);
+ if (dissenter) NSLog(@"ok");
+
+ DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}}
+ if (session) NSLog(@"ok");
+}
+
+// Test retain/release checker with CFString and CFMutableArray.
+void f11() {
+ // Create the array.
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+
+ // Create a string.
+ CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
+ kCFStringEncodingUTF8);
+
+ // Add the string to the array.
+ CFArrayAppendValue(A, s1);
+
+ // Decrement the reference count.
+ CFRelease(s1); // no-warning
+
+ // Get the string. We don't own it.
+ s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
+
+ // Release the array.
+ CFRelease(A); // no-warning
+
+ // Release the string. This is a bug.
+ CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// PR 3337: Handle functions declared using typedefs.
+typedef CFTypeRef CREATEFUN();
+CREATEFUN MyCreateFun;
+
+void f12() {
+ CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
+}
+
+void f13_autorelease() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+ [(id) A autorelease]; // no-warning
+}
+
+void f13_autorelease_b() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+ [(id) A autorelease];
+ [(id) A autorelease]; // expected-warning{{Object sent -autorelease too many times}}
+}
+
+CFMutableArrayRef f13_autorelease_c() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+ [(id) A autorelease];
+ [(id) A autorelease];
+ return A; // expected-warning{{Object sent -autorelease too many times}}
+}
+
+CFMutableArrayRef f13_autorelease_d() {
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+ [(id) A autorelease];
+ [(id) A autorelease];
+ CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}}
+ CFRelease(B); // no-warning
+ while (1) {}
+}
+
+
+// This case exercises the logic where the leak site is the same as the allocation site.
+void f14_leakimmediately() {
+ CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+}
+
+// Test that we track an allocated object beyond the point where the *name*
+// of the variable storing the reference is no longer live.
+void f15() {
+ // Create the array.
+ CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
+ CFMutableArrayRef *B = &A;
+ // At this point, the name 'A' is no longer live.
+ 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
+// of tracked objects to ivars.
+@interface SelfIvarTest : NSObject {
+ id myObj;
+}
+- (void)test_self_tracking;
+@end
+
+@implementation SelfIvarTest
+- (void)test_self_tracking {
+ myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+}
+@end
+
+// Test return of non-owned objects in contexts where an owned object
+// is expected.
+@interface TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString;
+@end
+
+@implementation TestReturnNotOwnedWhenExpectedOwned
+- (NSString*)newString {
+ NSString *s = [NSString stringWithUTF8String:"hello"];
+ return s; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
+@end
+
+// <rdar://problem/6659160>
+int isFoo(char c);
+
+static void rdar_6659160(char *inkind, char *inname)
+{
+ // We currently expect that [NSObject alloc] cannot fail. This
+ // will be a toggled flag in the future. It can indeed return null, but
+ // Cocoa programmers generally aren't expected to reason about out-of-memory
+ // conditions.
+ NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}}
+
+ // We do allow stringWithUTF8String to fail. This isn't really correct, as
+ // far as returning 0. In most error conditions it will throw an exception.
+ // If allocation fails it could return 0, but again this
+ // isn't expected.
+ NSString *name = [NSString stringWithUTF8String:inname];
+ if(!name)
+ return;
+
+ const char *kindC = 0;
+ const char *nameC = 0;
+
+ // In both cases, we cannot reach a point down below where we
+ // dereference kindC or nameC with either being null. This is because
+ // we assume that [NSObject alloc] doesn't fail and that we have the guard
+ // up above.
+
+ if(kind)
+ kindC = [kind UTF8String];
+ if(name)
+ nameC = [name UTF8String];
+ if(!isFoo(kindC[0])) // expected-warning{{null}}
+ return;
+ if(!isFoo(nameC[0])) // no-warning
+ return;
+
+ [kind release];
+ [name release]; // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming
+// conventions with respect to 'return'ing ownership.
+@interface PR3677: NSObject @end
+@implementation PR3677
++ (id)allocWithZone:(NSZone *)inZone {
+ return [super allocWithZone:inZone]; // no-warning
+}
+@end
+
+// PR 3820 - Reason about calls to -dealloc
+void pr3820_DeallocInsteadOfRelease(void)
+{
+ id foo = [[NSString alloc] init]; // no-warning
+ [foo dealloc];
+ // foo is not leaked, since it has been deallocated.
+}
+
+void pr3820_ReleaseAfterDealloc(void)
+{
+ id foo = [[NSString alloc] init];
+ [foo dealloc];
+ [foo release]; // expected-warning{{used after it is release}}
+ // NSInternalInconsistencyException: message sent to deallocated object
+}
+
+void pr3820_DeallocAfterRelease(void)
+{
+ NSLog(@"\n\n[%s]", __FUNCTION__);
+ id foo = [[NSString alloc] init];
+ [foo release];
+ [foo dealloc]; // expected-warning{{used after it is released}}
+ // message sent to released object
+}
+
+// From <rdar://problem/6704930>. The problem here is that 'length' binds to
+// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to
+// reason about '($0 - 1) > constant'. As a temporary hack, we drop the value
+// of '($0 - 1)' and conjure a new symbol.
+void rdar6704930(unsigned char *s, unsigned int length) {
+ NSString* name = 0;
+ if (s != 0) {
+ if (length > 0) {
+ while (length > 0) {
+ if (*s == ':') {
+ ++s;
+ --length;
+ name = [[NSString alloc] init]; // no-warning
+ break;
+ }
+ ++s;
+ --length;
+ }
+ if ((length == 0) && (name != 0)) {
+ [name release];
+ name = 0;
+ }
+ if (length == 0) { // no ':' found -> use it all as name
+ name = [[NSString alloc] init]; // no-warning
+ }
+ }
+ }
+
+ if (name != 0) {
+ [name release];
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6833332>
+// One build of the analyzer accidentally stopped tracking the allocated
+// object after the 'retain'.
+//===----------------------------------------------------------------------===//
+
+@interface rdar_6833332 : NSObject <NSApplicationDelegate> {
+ NSWindow *window;
+}
+@property (nonatomic, retain) NSWindow *window;
+@end
+
+@implementation rdar_6833332
+@synthesize window;
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}}
+
+ [dict setObject:@"foo" forKey:@"bar"];
+
+ NSLog(@"%@", dict);
+}
+- (void)dealloc {
+ [window release];
+ [super dealloc];
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6257780> clang checker fails to catch use-after-release
+//===----------------------------------------------------------------------===//
+
+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 that is not owned at this point by the caller}}
+ [pool drain];
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
+//===----------------------------------------------------------------------===//
+
+void rdar_6866843() {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];
+ NSArray* array = [[NSArray alloc] init];
+ [dictionary setObject:array forKey:@"key"];
+ [array release];
+ // Using 'array' here should be fine
+ NSLog(@"array = %@\n", array); // no-warning
+ // Now the array is released
+ [dictionary release];
+ [pool drain];
+}
+
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects
+//===----------------------------------------------------------------------===//
+
+typedef CFTypeRef OtherRef;
+
+@interface RDar6877235 : NSObject {}
+- (CFTypeRef)_copyCFTypeRef;
+- (OtherRef)_copyOtherRef;
+@end
+
+@implementation RDar6877235
+- (CFTypeRef)_copyCFTypeRef {
+ return [[NSString alloc] init]; // no-warning
+}
+- (OtherRef)_copyOtherRef {
+ return [[NSString alloc] init]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+//<rdar://problem/6320065> false positive - init method returns an object
+// owned by caller
+//===----------------------------------------------------------------------===//
+
+@interface RDar6320065 : NSObject {
+ NSString *_foo;
+}
+- (id)initReturningNewClass;
+- (id)initReturningNewClassBad;
+- (id)initReturningNewClassBad2;
+@end
+
+@interface RDar6320065Subclass : RDar6320065
+@end
+
+@implementation RDar6320065
+- (id)initReturningNewClass {
+ [self release];
+ self = [[RDar6320065Subclass alloc] init]; // no-warning
+ return self;
+}
+- (id)initReturningNewClassBad {
+ [self release];
+ [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}}
+ return self;
+}
+- (id)initReturningNewClassBad2 {
+ [self release];
+ self = [[RDar6320065Subclass alloc] init];
+ return [self autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
+
+@end
+
+@implementation RDar6320065Subclass
+@end
+
+int RDar6320065_test() {
+ RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning
+ [test release];
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// <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 {}
+- (NSString*) NoCopyString;
+- (NSString*) noCopyString;
+@end
+
+@implementation RDar6859457
+- (NSString*) NoCopyString { return [[NSString alloc] init]; } // no-warning
+- (NSString*) noCopyString { return [[NSString alloc] init]; } // no-warning
+@end
+
+void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) {
+ [x NoCopyString]; // expected-warning{{leak}}
+ [x noCopyString]; // expected-warning{{leak}}
+ [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning
+ [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
+// PR 4230 - an autorelease pool is not necessarily leaked during a premature
+// return
+//===----------------------------------------------------------------------===//
+
+static void PR4230(void)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning
+ NSString *object = [[[NSString alloc] init] autorelease]; // no-warning
+ return;
+}
+
+//===----------------------------------------------------------------------===//
+// Method name that has a null IdentifierInfo* for its first selector slot.
+// This test just makes sure that we handle it.
+//===----------------------------------------------------------------------===//
+
+@interface TestNullIdentifier
+@end
+
+@implementation TestNullIdentifier
++ (id):(int)x, ... {
+ return [[NSString alloc] init]; // expected-warning{{leak}}
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6893565> don't flag leaks for return types that cannot be
+// determined to be CF types
+//===----------------------------------------------------------------------===//
+
+// We don't know if 'struct s6893565' represents a Core Foundation type, so
+// we shouldn't emit an error here.
+typedef struct s6893565* TD6893565;
+
+@interface RDar6893565 {}
+-(TD6893565)newThing;
+@end
+
+@implementation RDar6893565
+-(TD6893565)newThing {
+ return (TD6893565) [[NSString alloc] init]; // no-warning
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods
+//===----------------------------------------------------------------------===//
+
+void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context,
+ NSString *str, CIImage *img, CGRect rect,
+ CIFormat form, CGColorSpaceRef cs) {
+ [view createSnapshotImageOfType:str]; // expected-warning{{leak}}
+ [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}}
+ [context createCGImage:img fromRect:rect]; // expected-warning{{leak}}
+ [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:]
+// misinterpreted by clang scan-build
+//===----------------------------------------------------------------------===//
+
+void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) {
+ [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release
+// checker
+//===----------------------------------------------------------------------===//
+
+void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options, const char * bsdName) {
+ IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}}
+}
+
+void IOServiceMatching_wrapper(const char * name) {
+ IOServiceMatching(name); // expected-warning{{leak}}
+}
+
+void IOServiceNameMatching_wrapper(const char * name) {
+ IOServiceNameMatching(name); // expected-warning{{leak}}
+}
+
+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 ) {
+
+ CFDictionaryRef matching = CreateDict();
+ CFRelease(matching);
+ IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}}
+ wakePort, reference, notification);
+}
+
+void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) {
+ IORegistryEntryIDMatching(entryID); // expected-warning{{leak}}
+}
+
+void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options,
+ const char * path) {
+ IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}}
+}
+
+void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) {
+ CFDictionaryRef matching = CreateDict();
+ IOServiceGetMatchingService(masterPort, matching);
+ CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) {
+ CFDictionaryRef matching = CreateDict();
+ IOServiceGetMatchingServices(masterPort, matching, existing);
+ CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType,
+ IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) {
+
+ CFDictionaryRef matching = CreateDict();
+ IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification);
+ CFRelease(matching); // expected-warning{{used after it is released}}
+}
+
+//===----------------------------------------------------------------------===//
+// Test of handling objects whose references "escape" to containers.
+//===----------------------------------------------------------------------===//
+
+void CFDictionaryAddValue();
+
+// <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) ;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7358899> False leak associated with
+// CGBitmapContextCreateWithData
+//===----------------------------------------------------------------------===//
+typedef uint32_t CGBitmapInfo;
+typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data);
+
+CGContextRef CGBitmapContextCreateWithData(void *data,
+ size_t width, size_t height, size_t bitsPerComponent,
+ size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo,
+ CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo);
+
+void rdar_7358899(void *data,
+ size_t width, size_t height, size_t bitsPerComponent,
+ size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo,
+ CGBitmapContextReleaseDataCallback releaseCallback) {
+
+ // 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
+
+ CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}}
+ bytesPerRow, space, bitmapInfo, releaseCallback, number);
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to
+// start before '_' when determining Cocoa fundamental rule
+//
+// Previously the retain/release checker just skipped prefixes before the
+// first '_' entirely. Now the checker honors the prefix if it results in a
+// recognizable naming convention (e.g., 'new', 'init').
+//===----------------------------------------------------------------------===//
+
+@interface RDar7265711 {}
+- (id) new_stuff;
+@end
+
+void rdar7265711_a(RDar7265711 *x) {
+ id y = [x new_stuff]; // expected-warning{{leak}}
+}
+
+void rdar7265711_b(RDar7265711 *x) {
+ id y = [x new_stuff]; // no-warning
+ [y release];
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a
+// retained reference
+//===----------------------------------------------------------------------===//
+
+@interface NSCursor : NSObject
++ (NSCursor *)dragCopyCursor;
+@end
+
+void rdar7306898(void) {
+ // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence
+ // implying a 'copy' of something.
+ NSCursor *c = [NSCursor dragCopyCursor]; // no-warning
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class
+// directly is not likely what the user intended
+//===----------------------------------------------------------------------===//
+
+@interface RDar7252064 : NSObject @end
+void rdar7252064(void) {
+ [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+ [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+ [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}}
+ [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}}
+}
+
+//===----------------------------------------------------------------------===//
+// Tests of ownership attributes.
+//===----------------------------------------------------------------------===//
+
+typedef NSString* MyStringTy;
+
+@protocol FooP;
+
+@interface TestOwnershipAttr : NSObject
+- (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 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}}
+}
+
+void test_attr_1b(TestOwnershipAttr *X) {
+ NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
+}
+
+@interface MyClassTestCFAttr : NSObject {}
+- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;
+- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED;
+- (NSDate*) alsoReturnsRetained;
+- (CFDateRef) alsoReturnsRetainedAsCF;
+- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED;
+@end
+
+CF_RETURNS_RETAINED
+CFDateRef returnsRetainedCFDate() {
+ return CFDateCreate(0, CFAbsoluteTimeGetCurrent());
+}
+
+@implementation MyClassTestCFAttr
+- (NSDate*) returnsCFRetained {
+ 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();
+}
+
+//===----------------------------------------------------------------------===//
+// Test uses of blocks (closures)
+//===----------------------------------------------------------------------===//
+
+void test_blocks_1_pos(void) {
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+ ^{}();
+}
+
+void test_blocks_1_indirect_release(void) {
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+ ^{ [number release]; }();
+}
+
+void test_blocks_1_indirect_retain(void) {
+ // Eventually this should be reported as a leak.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+ ^{ [number retain]; }();
+}
+
+void test_blocks_1_indirect_release_via_call(void) {
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+ ^(NSObject *o){ [o release]; }(number);
+}
+
+void test_blocks_1_indirect_retain_via_call(void) {
+ // Eventually this should be reported as a leak.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+ ^(NSObject *o){ [o retain]; }(number);
+}
+
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
new file mode 100644
index 0000000..7a71235
--- /dev/null
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -analyzer-check-security-syntactic %s -verify
+
+// This file complements 'security-syntax-checks.m', but tests that we omit
+// specific checks on platforms where they don't make sense.
+
+// Omit the 'rand' check since 'arc4random' is not available on Linux.
+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(); // no-warning
+ drand48(); // no-warning
+ erand48(a); // no-warning
+ jrand48(a); // no-warning
+ lcong48(a); // no-warning
+ lrand48(); // no-warning
+ mrand48(); // no-warning
+ nrand48(a); // no-warning
+ rand_r(&b); // no-warning
+ random(); // no-warning
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
new file mode 100644
index 0000000..8dd859a
--- /dev/null
+++ b/test/Analysis/security-syntax-checks.m
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-check-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}}
+}
+
+int getpw(unsigned int uid, char *buf);
+
+void test_getpw() {
+ char buff[1024];
+ getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid().}}
+}
+
+// <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 abort(void);
+
+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}}
+}
+
+char *mktemp(char *buf);
+
+void test_mktemp() {
+ char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
+}
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
new file mode 100644
index 0000000..82fda04
--- /dev/null
+++ b/test/Analysis/sizeofpointer.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -analyze -warn-sizeof-pointer -verify %s
+
+struct s {
+};
+
+int f(struct s *p) {
+ return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result.}}
+}
diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c
new file mode 100644
index 0000000..f8cadbe
--- /dev/null
+++ b/test/Analysis/stack-addr-ps.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -fblocks -verify %s
+
+int* f1() {
+ int x = 0;
+ return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}}
+}
+
+int* f2(int y) {
+ return &y; // expected-warning{{Address of stack memory associated with local variable 'y' returned.}} expected-warning{{address of stack memory associated with local variable 'y' returned}}
+}
+
+int* f3(int x, int *y) {
+ int w = 0;
+
+ if (x)
+ y = &w;
+
+ return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned.}}
+}
+
+void* compound_literal(int x, int y) {
+ if (x)
+ return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}}
+
+ int* array[] = {};
+ struct s { int z; double y; int w; };
+
+ if (y)
+ return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}}
+
+
+ void* p = &((struct s){ 42, 0.4, x ? 42 : 0 });
+ return p; // expected-warning{{Address of stack memory}}
+}
+
+void* alloca_test() {
+ void* p = __builtin_alloca(10);
+ return p; // expected-warning{{Address of stack memory}}
+}
+
+int array_test(int x[2]) {
+ return x[0]; // no-warning
+}
+
+struct baz {
+ int x;
+ int y[2];
+};
+
+int struct_test(struct baz byVal, int flag) {
+ if (flag)
+ return byVal.x; // no-warning
+ else {
+ return byVal.y[0]; // no-warning
+ }
+}
+
+typedef int (^ComparatorBlock)(int a, int b);
+ComparatorBlock test_return_block(void) {
+ ComparatorBlock b = ^int(int a, int b){ return a > b; };
+ return b; // expected-warning{{Address of stack-allocated block declared on line 61 returned to caller}}
+}
+
+ComparatorBlock test_return_block_neg_aux(void);
+ComparatorBlock test_return_block_neg(void) {
+ ComparatorBlock b = test_return_block_neg_aux();
+ return b; // no-warning
+}
+
+// <rdar://problem/7523821>
+int *rdar_7523821_f2() {
+ int a[3];
+ return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}}
+};
+
+
diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m
new file mode 100644
index 0000000..4061150
--- /dev/null
+++ b/test/Analysis/uninit-msg-expr.m
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from
+// Foundation.h (Mac OS X).
+//
+// It includes the basic definitions for the test cases below.
+// Not directly including Foundation.h directly makes this test case
+// both svelte and portable to non-Mac platforms.
+//===----------------------------------------------------------------------===//
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+@class NSString, NSData;
+@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
+typedef struct {} NSFastEnumerationState;
+@protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+@end
+@class NSData, NSIndexSet, NSString, NSURL;
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSArray (NSArrayCreation)
++ (id)array;
+- (NSUInteger)length;
+- (void)addObject:(id)object;
+@end
+extern NSString * const NSUndoManagerCheckpointNotification;
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+unsigned f1() {
+ NSString *aString;
+ return [aString length]; // expected-warning {{Receiver in message expression is a garbage value}}
+}
+
+unsigned f2() {
+ NSString *aString = 0;
+ return [aString length]; // no-warning
+}
+
+void f3() {
+ NSMutableArray *aArray = [NSArray array];
+ NSString *aString;
+ [aArray addObject:aString]; // expected-warning {{Pass-by-value argument in message expression is undefined.}}
+}
diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m
new file mode 100644
index 0000000..1409dbd
--- /dev/null
+++ b/test/Analysis/uninit-ps-rdar6145427.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -verify -analyzer-store=basic -analyzer-check-objc-mem %s
+// RUN: %clang_cc1 -analyze -verify -analyzer-store=region -analyzer-check-objc-mem %s
+
+// Delta-Debugging reduced preamble.
+typedef signed char BOOL;
+typedef unsigned int 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; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} + (id)alloc; @end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; @end
+@class NSString, NSData;
+typedef struct _NSPoint {} NSRange;
+@interface NSValue (NSValueRangeExtensions)
++ (NSValue *)valueWithRange:(NSRange)range;
+- (id)objectAtIndex:(NSUInteger)index;
+@end
+@interface NSAutoreleasePool : NSObject {} - (void)drain; @end
+extern NSString * const NSBundleDidLoadNotification;
+typedef struct {} NSDecimal;
+@interface NSNetService : NSObject {} - (id)init; @end
+extern NSString * const NSUndoManagerCheckpointNotification;
+
+// Test case: <rdar://problem/6145427>
+
+int main (int argc, const char * argv[]) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ id someUnintializedPointer = [someUnintializedPointer objectAtIndex:0]; // expected-warning{{Receiver in message expression is a garbage value}}
+ NSLog(@"%@", someUnintializedPointer);
+ [pool drain];
+ return 0;
+}
diff --git a/test/Analysis/uninit-vals-ps-region.c b/test/Analysis/uninit-vals-ps-region.c
new file mode 100644
index 0000000..44f506e
--- /dev/null
+++ b/test/Analysis/uninit-vals-ps-region.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+struct s {
+ int data;
+};
+
+struct s global;
+
+void g(int);
+
+void f4() {
+ int a;
+ if (global.data == 0)
+ a = 3;
+ 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_unit_aux2(int);
+void test_uninit_pos() {
+ struct TestUninit v1 = { 0, 0 };
+ struct TestUninit v2 = test_uninit_aux();
+ int z;
+ v1.y = z; // expected-warning{{Assigned value is garbage or undefined}}
+ test_unit_aux2(v2.x + v1.y);
+}
+void test_uninit_pos_2() {
+ struct TestUninit v1 = { 0, 0 };
+ struct TestUninit v2;
+ test_unit_aux2(v2.x + v1.y); // expected-warning{{The left operand of '+' is a garbage value}}
+}
+void test_uninit_pos_3() {
+ struct TestUninit v1 = { 0, 0 };
+ struct TestUninit v2;
+ test_unit_aux2(v1.y + v2.x); // 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
new file mode 100644
index 0000000..4abd413
--- /dev/null
+++ b/test/Analysis/uninit-vals-ps.c
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+struct FPRec {
+ void (*my_func)(int * x);
+};
+
+int bar(int x);
+
+int f1_a(struct FPRec* foo) {
+ int x;
+ (*foo->my_func)(&x);
+ return bar(x)+1; // no-warning
+}
+
+int f1_b() {
+ int x;
+ return bar(x)+1; // expected-warning{{Pass-by-value argument in function call is undefined.}}
+}
+
+int f2() {
+
+ int x;
+
+ if (x+1) // expected-warning{{The left operand of '+' is a garbage value}}
+ return 1;
+
+ return 2;
+}
+
+int f2_b() {
+ int x;
+
+ 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{{The left operand of '>' is a garbage value}}
+ return 0;
+ else
+ return 1;
+}
+
+void f4_aux(float* x);
+float f4(void) {
+ float x;
+ f4_aux(&x);
+ return x; // no-warning
+}
+
+struct f5_struct { int x; };
+void f5_aux(struct f5_struct* s);
+int f5(void) {
+ struct f5_struct s;
+ f5_aux(&s);
+ return s.x; // no-warning
+}
+
+int ret_uninit() {
+ int i;
+ int *p = &i;
+ return *p; // expected-warning{{Undefined or garbage value returned to caller}}
+}
+
+// <rdar://problem/6451816>
+typedef unsigned char Boolean;
+typedef const struct __CFNumber * CFNumberRef;
+typedef signed long CFIndex;
+typedef CFIndex CFNumberType;
+typedef unsigned long UInt32;
+typedef UInt32 CFStringEncoding;
+typedef const struct __CFString * CFStringRef;
+extern Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
+extern CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
+
+CFStringRef rdar_6451816(CFNumberRef nr) {
+ CFStringEncoding encoding;
+ // &encoding is casted to void*. This test case tests whether or not
+ // we properly invalidate the value of 'encoding'.
+ CFNumberGetValue(nr, 9, &encoding);
+ 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
new file mode 100644
index 0000000..b0769ba
--- /dev/null
+++ b/test/Analysis/uninit-vals.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -analyze -warn-uninit-values -verify %s
+
+int f1() {
+ int x;
+ return x; // expected-warning {{use of uninitialized variable}}
+}
+
+int f2(int x) {
+ int y;
+ int z = x + y; // expected-warning {{use of uninitialized variable}}
+ return z;
+}
+
+
+int f3(int x) {
+ int y;
+ return x ? 1 : y; // expected-warning {{use of uninitialized variable}}
+}
+
+int f4(int x) {
+ int y;
+ if (x) y = 1;
+ return y; // expected-warning {{use of uninitialized variable}}
+}
+
+void f5() {
+ int a;
+ a = 30; // no-warning
+}
+
+void f6(int i) {
+ int x;
+ for (i = 0 ; i < 10; i++)
+ printf("%d",x++); // expected-warning {{use of uninitialized variable}} \
+ // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \
+ // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+}
+
+void f7(int i) {
+ int x = i;
+ int y;
+ for (i = 0; i < 10; i++ ) {
+ printf("%d",x++); // no-warning
+ x += y; // expected-warning {{use of uninitialized variable}}
+ }
+}
+
+int f8(int j) {
+ int x = 1, y = x + 1;
+ if (y) // no-warning
+ return x;
+ return y;
+}
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
new file mode 100644
index 0000000..2f7f29c
--- /dev/null
+++ b/test/Analysis/uninit-vals.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+
+typedef unsigned int NSUInteger;
+
+@interface A
+- (NSUInteger)foo;
+@end
+
+NSUInteger f8(A* x){
+ const NSUInteger n = [x foo];
+ int* bogus;
+
+ if (n > 0) { // tests const cast transfer function logic
+ NSUInteger i;
+
+ for (i = 0; i < n; ++i)
+ bogus = 0;
+
+ if (bogus) // no-warning
+ return n+1;
+ }
+
+ return n;
+}
diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m
new file mode 100644
index 0000000..180faf8
--- /dev/null
+++ b/test/Analysis/unions-region.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -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
new file mode 100644
index 0000000..600f0e2
--- /dev/null
+++ b/test/Analysis/unused-ivars.m
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-check-objc-unused-ivars %s -verify
+
+//===--- 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
+
+// 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
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/6260004> Detect that ivar is in use, if used in category
+// in the same file as the implementation
+//===----------------------------------------------------------------------===//
+
+@protocol Protocol6260004
+- (id) getId;
+@end
+
+@interface RDar6260004 {
+@private
+ id x; // no-warning
+}
+@end
+@implementation RDar6260004 @end
+@implementation RDar6260004 (Protocol6260004)
+- (id) getId {
+ return x;
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7254495> - ivars referenced by lexically nested functions
+// should not be flagged as unused
+//===----------------------------------------------------------------------===//
+
+@interface RDar7254495 {
+@private
+ int x; // no-warning
+}
+@end
+
+@implementation RDar7254495
+int radar_7254495(RDar7254495 *a) {
+ return a->x;
+}
+@end