Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
      2 
      3 #include <stdarg.h>
      4 
      5 //===----------------------------------------------------------------------===//
      6 // The following code is reduced using delta-debugging from
      7 // Foundation.h (Mac OS X).
      8 //
      9 // It includes the basic definitions for the test cases below.
     10 // Not directly including Foundation.h directly makes this test case 
     11 // both svelte and portable to non-Mac platforms.
     12 //===----------------------------------------------------------------------===//
     13 
     14 typedef signed char BOOL;
     15 typedef unsigned int NSUInteger;
     16 typedef struct _NSZone NSZone;
     17 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
     18 @protocol NSObject  - (BOOL)isEqual:(id)object;
     19 @end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
     20 @end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
     21 @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
     22 @interface NSObject <NSObject> {} @end
     23 extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
     24 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
     25 - (NSUInteger)length;
     26 + (id)stringWithFormat:(NSString *)format, ...;
     27 @end
     28 @interface NSSimpleCString : NSString {} @end
     29 @interface NSConstantString : NSSimpleCString @end
     30 extern void *_NSConstantStringClassReference;
     31 typedef double NSTimeInterval;
     32 @interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
     33 @class NSString, NSDictionary, NSArray;
     34 @interface NSException : NSObject <NSCopying, NSCoding> {}
     35 + (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
     36 - (void)raise;
     37 @end
     38 @interface NSException (NSExceptionRaisingConveniences)
     39 + (void)raise:(NSString *)name format:(NSString *)format, ...;
     40 + (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
     41 @end
     42 
     43 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), };
     44 
     45 //===----------------------------------------------------------------------===//
     46 // Test cases.
     47 //===----------------------------------------------------------------------===//
     48 
     49 int f1(int *x, NSString* s) {
     50   
     51   if (x) ++x;
     52   
     53   [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
     54   
     55   return *x; // no-warning
     56 }
     57 
     58 int f2(int *x, ...) {
     59   
     60   if (x) ++x;
     61   va_list alist;
     62   va_start(alist, x);
     63   
     64   [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
     65   
     66   return *x; // no-warning
     67 }
     68 
     69 int f3(int* x) {
     70   
     71   if (x) ++x;
     72   
     73   [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];
     74 
     75   return *x; // no-warning
     76 }
     77 
     78 
     79 @interface CustomException : NSException
     80 @end
     81 
     82 int testCustomException(int *x) {
     83   if (x != 0) return 0;
     84 
     85   [CustomException raise:@"Blah" format:@"abc"];
     86 
     87   return *x; // no-warning
     88 }
     89 
     90 // Test that __attribute__((analyzer_noreturn)) has the intended
     91 // effect on Objective-C methods.
     92 
     93 @interface Radar11634353
     94 + (void) doesNotReturn __attribute__((analyzer_noreturn));
     95 - (void) alsoDoesNotReturn __attribute__((analyzer_noreturn));
     96 @end
     97 
     98 void test_rdar11634353() {
     99   [Radar11634353 doesNotReturn];
    100   int *p = 0;
    101   *p = 0xDEADBEEF; // no-warning
    102 }
    103 
    104 void test_rdar11634352_instance(Radar11634353 *o) {
    105   [o alsoDoesNotReturn];
    106   int *p = 0;
    107   *p = 0xDEADBEEF; // no-warning
    108 }
    109 
    110 void test_rdar11634353_positive() {
    111   int *p = 0;
    112   *p = 0xDEADBEEF; // expected-warning {{null pointer}}
    113 }
    114 
    115 // Test analyzer_noreturn on category methods.
    116 @interface NSException (OBExtensions)
    117 + (void)raise:(NSString *)name reason:(NSString *)reason __attribute__((analyzer_noreturn));
    118 @end
    119 
    120 void PR11959(int *p) {
    121   if (!p)
    122     [NSException raise:@"Bad Pointer" reason:@"Who knows?"];
    123   *p = 0xDEADBEEF; // no-warning
    124 }
    125 
    126 // Test that hard-coded Microsoft _wassert name is recognized as a noreturn
    127 #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(#_Expression, __FILE__, __LINE__), 0) )
    128 extern void _wassert(const char * _Message, const char *_File, unsigned _Line);
    129 void test_wassert() {
    130   assert(0);
    131   int *p = 0;
    132   *p = 0xDEADBEEF; // no-warning
    133 }
    134 #undef assert
    135 
    136 // Test that hard-coded Android __assert2 name is recognized as a noreturn
    137 #define assert(_Expression) ((_Expression) ? (void)0 : __assert2(0, 0, 0, 0));
    138 extern void __assert2(const char *, int, const char *, const char *);
    139 extern void _wassert(const char * _Message, const char *_File, unsigned _Line);
    140 void test___assert2() {
    141   assert(0);
    142   int *p = 0;
    143   *p = 0xDEADBEEF; // no-warning
    144 }
    145 #undef assert
    146