diff options
author | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
commit | c49018d9cce52d8c9f34b44865ec3ba8e89a1488 (patch) | |
tree | c5e9e10bc189de0058aa763c47b9920a8351b7df /test/Analysis | |
parent | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (diff) | |
download | FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.zip FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.tar.gz |
Vendor import of clang trunk r132879:
http://llvm.org/svn/llvm-project/cfe/trunk@132879
Diffstat (limited to 'test/Analysis')
-rw-r--r-- | test/Analysis/CFNumber.c | 7 | ||||
-rw-r--r-- | test/Analysis/bstring.c | 37 | ||||
-rw-r--r-- | test/Analysis/misc-ps-cxx0x.cpp | 11 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.cpp | 19 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.m | 24 | ||||
-rw-r--r-- | test/Analysis/misc-ps.c | 83 | ||||
-rw-r--r-- | test/Analysis/misc-ps.m | 25 | ||||
-rw-r--r-- | test/Analysis/plist-output-alternate.m | 9 | ||||
-rw-r--r-- | test/Analysis/retain-release.m | 10 | ||||
-rw-r--r-- | test/Analysis/retain-release.mm | 306 | ||||
-rw-r--r-- | test/Analysis/string.c | 174 |
11 files changed, 627 insertions, 78 deletions
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c index dd57cd9..11af0747 100644 --- a/test/Analysis/CFNumber.c +++ b/test/Analysis/CFNumber.c @@ -22,10 +22,15 @@ 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) { +__attribute__((cf_returns_retained)) 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.}} } +// test that the attribute overrides the naming convention. +__attribute__((cf_returns_not_retained)) CFNumberRef CreateNum(unsigned char x) { + return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{leak}} +} + 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/bstring.c b/test/Analysis/bstring.c index 1f6839d..68bbb1a 100644 --- a/test/Analysis/bstring.c +++ b/test/Analysis/bstring.c @@ -136,13 +136,38 @@ void memcpy13() { memcpy(a, 0, 0); // no-warning } +void memcpy_unknown_size (size_t n) { + char a[4], b[4] = {1}; + if (memcpy(a, b, n) != a) + (void)*(char*)0; // no-warning +} + +void memcpy_unknown_size_warn (size_t n) { + char a[4]; + if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // mempcpy() //===----------------------------------------------------------------------=== +#ifdef VARIANT + +#define __mempcpy_chk BUILTIN(__mempcpy_chk) +void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n, + size_t destlen); + +#define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1) + +#else /* VARIANT */ + #define mempcpy BUILTIN(mempcpy) void *mempcpy(void *restrict s1, const void *restrict s2, size_t n); +#endif /* VARIANT */ + + void mempcpy0 () { char src[] = {1, 2, 3, 4}; char dst[5] = {0}; @@ -233,6 +258,18 @@ void mempcpy13() { mempcpy(a, 0, 0); // no-warning } +void mempcpy_unknown_size_warn (size_t n) { + char a[4]; + if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} + (void)*(char*)0; // no-warning +} + +void mempcpy_unknownable_size (char *src, float n) { + char a[4]; + // This used to crash because we don't model floats. + mempcpy(a, src, (size_t)n); +} + //===----------------------------------------------------------------------=== // memmove() //===----------------------------------------------------------------------=== diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp new file mode 100644 index 0000000..f21e82c --- /dev/null +++ b/test/Analysis/misc-ps-cxx0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang --analyze -std=c++0x %s -Xclang -verify + +void test_static_assert() { + static_assert(sizeof(void *) == sizeof(void*), "test_static_assert"); +} + +void test_analyzer_working() { + int *p = 0; + *p = 0xDEADBEEF; // expected-warning {{null}} +} + diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp index b122bff..7959359 100644 --- a/test/Analysis/misc-ps-region-store.cpp +++ b/test/Analysis/misc-ps-region-store.cpp @@ -395,3 +395,22 @@ unsigned test_invalidate_in_ctor_new() { return x; // no-warning } +// Test assigning into a symbolic offset. +struct TestAssignIntoSymbolicOffset { + int **stuff[100]; + void test(int x, int y); +}; + +void TestAssignIntoSymbolicOffset::test(int x, int y) { + x--; + if (x > 8 || x < 0) + return; + if (stuff[x]) + return; + if (!stuff[x]) { + stuff[x] = new int*[y+1]; + // Previously triggered a null dereference. + stuff[x][y] = 0; // no-warning + } +} + diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index be0356d..27f12c9 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -1299,3 +1299,27 @@ RDar9163742_Rect RDar9163742_IntegralRect(RDar9163742_Rect frame) return RDar9163742_RectIntegral(integralFrame); // no-warning; all fields initialized } +// Test correct handling of prefix '--' operator. +void rdar9444714() { + int x; + char str[ 32 ]; + char buf[ 32 ]; + char * dst; + char * ptr; + + x = 1234; + dst = str; + ptr = buf; + do + { + *ptr++ = (char)( '0' + ( x % 10 ) ); + x /= 10; + } while( x > 0 ); + + while( ptr > buf ) + { + *dst++ = *( --( ptr ) ); // no-warning + } + *dst = '\0'; +} + diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c new file mode 100644 index 0000000..bef5b06 --- /dev/null +++ b/test/Analysis/misc-ps.c @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=deadcode -verify %s + +unsigned long strlen(const char *); + +int size_rdar9373039 = 1; +int rdar9373039() { + int x; + int j = 0; + + for (int i = 0 ; i < size_rdar9373039 ; ++i) + x = 1; + + // strlen doesn't invalidate the value of 'size_rdar9373039'. + int extra = (2 + strlen ("Clang") + ((4 - ((unsigned int) (2 + strlen ("Clang")) % 4)) % 4)) + (2 + strlen ("1.0") + ((4 - ((unsigned int) (2 + strlen ("1.0")) % 4)) % 4)); + + for (int i = 0 ; i < size_rdar9373039 ; ++i) + j += x; // no-warning + + return j; +} + +int foo_rdar9373039(const char *); + +int rdar93730392() { + int x; + int j = 0; + + for (int i = 0 ; i < size_rdar9373039 ; ++i) + x = 1; + + int extra = (2 + foo_rdar9373039 ("Clang") + ((4 - ((unsigned int) (2 + foo_rdar9373039 ("Clang")) % 4)) % 4)) + (2 + foo_rdar9373039 ("1.0") + ((4 - ((unsigned int) (2 + foo_rdar9373039 ("1.0")) % 4)) % 4)); // expected-warning {{never read}} + + for (int i = 0 ; i < size_rdar9373039 ; ++i) + j += x; // expected-warning {{garbage}} + + return j; +} + + +int PR8962 (int *t) { + // This should look through the __extension__ no-op. + if (__extension__ (t)) return 0; + return *t; // expected-warning {{null pointer}} +} + +int PR8962_b (int *t) { + // This should still ignore the nested casts + // which aren't handled by a single IgnoreParens() + if (((int)((int)t))) return 0; + return *t; // expected-warning {{null pointer}} +} + +int PR8962_c (int *t) { + // If the last element in a StmtExpr was a ParenExpr, it's still live + if (({ (t ? (_Bool)0 : (_Bool)1); })) return 0; + return *t; // no-warning +} + +int PR8962_d (int *t) { + // If the last element in a StmtExpr is an __extension__, it's still live + if (({ __extension__(t ? (_Bool)0 : (_Bool)1); })) return 0; + return *t; // no-warning +} + +int PR8962_e (int *t) { + // Redundant casts can mess things up! + // Environment used to skip through NoOp casts, but LiveVariables didn't! + if (({ (t ? (int)(int)0L : (int)(int)1L); })) return 0; + return *t; // no-warning +} + +int PR8962_f (int *t) { + // The StmtExpr isn't a block-level expression here, + // the __extension__ is. But the value should be attached to the StmtExpr + // anyway. Make sure the block-level check is /before/ IgnoreParens. + if ( __extension__({ + _Bool r; + if (t) r = 0; + else r = 1; + r; + }) ) return 0; + return *t; // no-warning +} diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 9de4afb..da84b24 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1301,3 +1301,28 @@ static void test(unsigned int bit_mask) } } } + +// Don't crash on code containing __label__. +int radar9414427_aux(); +void radar9414427() { + __label__ mylabel; + if (radar9414427_aux()) { + mylabel: do {} + while (0); + } +} + +// Analyze methods in @implementation (category) +@interface RDar9465344 +@end + +@implementation RDar9465344 (MyCategory) +- (void) testcategoryImpl { + int *p = 0x0; + *p = 0xDEADBEEF; // expected-warning {{null}} +} +@end + +@implementation RDar9465344 +@end + diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m index a7e3c3c..0f4d3ae 100644 --- a/test/Analysis/plist-output-alternate.m +++ b/test/Analysis/plist-output-alternate.m @@ -864,9 +864,9 @@ void rdar8331641(int x) { // CHECK: </array> // CHECK: </array> // CHECK: <key>extended_message</key> -// CHECK: <string>Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count (owning reference)</string> +// CHECK: <string>Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count</string> // CHECK: <key>message</key> -// CHECK: <string>Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count (owning reference)</string> +// CHECK: <string>Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count</string> // CHECK: </dict> // CHECK: <dict> // CHECK: <key>kind</key><string>control</string> @@ -994,9 +994,9 @@ void rdar8331641(int x) { // CHECK: </array> // CHECK: </array> // CHECK: <key>extended_message</key> -// CHECK: <string>Object allocated on line 53 and stored into 'value' is not referenced later in this execution path and has a retain count of +1 (object leaked)</string> +// CHECK: <string>Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1</string> // CHECK: <key>message</key> -// CHECK: <string>Object allocated on line 53 and stored into 'value' is not referenced later in this execution path and has a retain count of +1 (object leaked)</string> +// CHECK: <string>Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1</string> // CHECK: </dict> // CHECK: </array> // CHECK: <key>description</key><string>Potential leak of an object allocated on line 53 and stored into 'value'</string> @@ -1012,3 +1012,4 @@ void rdar8331641(int x) { // CHECK: </array> // CHECK: </dict> // CHECK: </plist> + diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 6782c90..7af14f1 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -280,7 +280,7 @@ CFAbsoluteTime f1() { CFRelease(date); CFDateGetAbsoluteTime(date); // no-warning CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} return t; } @@ -291,7 +291,7 @@ CFAbsoluteTime f2() { CFRelease(date); CFDateGetAbsoluteTime(date); // no-warning [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} return t; } @@ -343,7 +343,7 @@ CFDateRef f6(int x) { CFDateRef f7() { CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} CFRetain(date); - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} return date; } @@ -357,8 +357,8 @@ CFDateRef f8() { return date; } -CFDateRef f9() { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); +__attribute__((cf_returns_retained)) CFDateRef f9() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning int *p = 0; // When allocations fail, CFDateCreate can return null. if (!date) *p = 1; // expected-warning{{null}} diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm new file mode 100644 index 0000000..0faeb1a --- /dev/null +++ b/test/Analysis/retain-release.mm @@ -0,0 +1,306 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -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 +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#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 = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&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. +//===----------------------------------------------------------------------===// + +class SmartPointer { + id x; +public: + SmartPointer(id x) : x(x) {} + ~SmartPointer() { [x release]; } + + void adopt(id x); + void noAdopt(id x); +}; + +void test_positive() { + id x = [[NSObject alloc] init]; // expected-warning {{leak}} +} + +void test_smartpointer_1() { + id x = [[NSObject alloc] init]; // no-warning + SmartPointer foo(x); +} + +void test_smartpointer_2() { + id x = [[NSObject alloc] init]; // no-warning + SmartPointer foo(0); + foo.adopt(x); +} + +// FIXME: Eventually we want annotations to say whether or not +// a C++ method claims ownership of an Objective-C object. +void test_smartpointer_3() { + id x = [[NSObject alloc] init]; // no-warning + SmartPointer foo(0); + foo.noAdopt(x); +} + + diff --git a/test/Analysis/string.c b/test/Analysis/string.c index 19c838c..e6baf51 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -328,74 +328,6 @@ void strcpy_no_overflow(char *y) { } //===----------------------------------------------------------------------=== -// strncpy() -//===----------------------------------------------------------------------=== - -#ifdef VARIANT - -#define __strncpy_chk BUILTIN(__strncpy_chk) -char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); - -#define strncpy(a,b,c) __strncpy_chk(a,b,c, (size_t)-1) - -#else /* VARIANT */ - -#define strncpy BUILTIN(strncpy) -char *strncpy(char *restrict s1, const char *restrict s2, size_t n); - -#endif /* VARIANT */ - - -void strncpy_null_dst(char *x) { - strncpy(NULL, x, 1); // expected-warning{{Null pointer argument in call to byte string function}} -} - -void strncpy_null_src(char *x) { - strncpy(x, NULL, 1); // expected-warning{{Null pointer argument in call to byte string function}} -} - -void strncpy_fn(char *x) { - strncpy(x, (char*)&strncpy_fn, 1); // expected-warning{{Argument to byte string function is the address of the function 'strncpy_fn', which is not a null-terminated string}} -} - -void strncpy_effects(char *x, char *y) { - char a = x[0]; - - if (strncpy(x, y, strlen(y)) != x) - (void)*(char*)0; // no-warning - - if (strlen(x) != strlen(y)) - (void)*(char*)0; // no-warning - - if (a != x[0]) - (void)*(char*)0; // expected-warning{{null}} -} - -void strncpy_overflow(char *y) { - char x[4]; - if (strlen(y) == 4) - strncpy(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} -} - -void strncpy_len_overflow(char *y) { - char x[4]; - if (strlen(y) == 3) - strncpy(x, y, sizeof(x)); // no-warning -} - -void strncpy_no_overflow(char *y) { - char x[4]; - if (strlen(y) == 3) - strncpy(x, y, strlen(y)); // no-warning -} - -void strncpy_no_len_overflow(char *y) { - char x[4]; - if (strlen(y) == 4) - strncpy(x, y, sizeof(x)-1); // no-warning -} - -//===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------=== @@ -872,3 +804,109 @@ void strcasecmp_diff_length_3() { if (strcasecmp(x, y) != -1) (void)*(char*)0; // no-warning } + +//===----------------------------------------------------------------------=== +// strncasecmp() +//===----------------------------------------------------------------------=== + +#define strncasecmp BUILTIN(strncasecmp) +int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n); + +void strncasecmp_constant0() { + if (strncasecmp("abc", "Abc", 3) != 0) + (void)*(char*)0; // no-warning +} + +void strncasecmp_constant_and_var_0() { + char *x = "abc"; + if (strncasecmp(x, "Abc", 3) != 0) + (void)*(char*)0; // no-warning +} + +void strncasecmp_constant_and_var_1() { + char *x = "abc"; + if (strncasecmp("Abc", x, 3) != 0) + (void)*(char*)0; // no-warning +} + +void strncasecmp_0() { + char *x = "abc"; + char *y = "Abc"; + if (strncasecmp(x, y, 3) != 0) + (void)*(char*)0; // no-warning +} + +void strncasecmp_1() { + char *x = "Bcd"; + char *y = "abc"; + if (strncasecmp(x, y, 3) != 1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_2() { + char *x = "abc"; + char *y = "Bcd"; + if (strncasecmp(x, y, 3) != -1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_null_0() { + char *x = NULL; + char *y = "123"; + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} +} + +void strncasecmp_null_1() { + char *x = "123"; + char *y = NULL; + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} +} + +void strncasecmp_diff_length_0() { + char *x = "abcde"; + char *y = "aBd"; + if (strncasecmp(x, y, 5) != -1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_1() { + char *x = "abc"; + char *y = "aBdef"; + if (strncasecmp(x, y, 5) != -1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_2() { + char *x = "aBcDe"; + char *y = "abc"; + if (strncasecmp(x, y, 5) != 1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_3() { + char *x = "aBc"; + char *y = "abcde"; + if (strncasecmp(x, y, 5) != -1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_4() { + char *x = "abcde"; + char *y = "aBc"; + if (strncasecmp(x, y, 3) != 0) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_5() { + char *x = "abcde"; + char *y = "aBd"; + if (strncasecmp(x, y, 3) != -1) + (void)*(char*)0; // no-warning +} + +void strncasecmp_diff_length_6() { + char *x = "aBDe"; + char *y = "abc"; + if (strncasecmp(x, y, 3) != 1) + (void)*(char*)0; // no-warning +} |