misc-ps.m revision 54ca9b1d45fbfb0b3eeab581e0d10403cc922e62
1// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s && 2// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic-old-cast -analyzer-constraints=basic --verify -fblocks %s && 3// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s && 4// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic-old-cast -analyzer-constraints=range --verify -fblocks %s && 5// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && 6// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s 7 8typedef struct objc_selector *SEL; 9typedef signed char BOOL; 10typedef int NSInteger; 11typedef unsigned int NSUInteger; 12typedef struct _NSZone NSZone; 13@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator; 14@protocol NSObject - (BOOL)isEqual:(id)object; @end 15@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end 16@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end 17@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end 18@interface NSObject <NSObject> {} - (id)init; @end 19extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 20@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> 21- (NSUInteger)length; 22+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; 23@end extern NSString * const NSBundleDidLoadNotification; 24@interface NSAssertionHandler : NSObject {} 25+ (NSAssertionHandler *)currentHandler; 26- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; 27@end 28extern NSString * const NSConnectionReplyMode; 29typedef float CGFloat; 30typedef struct _NSPoint { 31 CGFloat x; 32 CGFloat y; 33} NSPoint; 34typedef struct _NSSize { 35 CGFloat width; 36 CGFloat height; 37} NSSize; 38typedef struct _NSRect { 39 NSPoint origin; 40 NSSize size; 41} NSRect; 42 43// Reduced test case from crash in <rdar://problem/6253157> 44@interface A @end 45@implementation A 46- (void)foo:(void (^)(NSObject *x))block { 47 if (!((block != ((void *)0)))) {} 48} 49@end 50 51// Reduced test case from crash in PR 2796; 52// http://llvm.org/bugs/show_bug.cgi?id=2796 53 54unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); } 55 56// Improvement to path-sensitivity involving compound assignments. 57// Addresses false positive in <rdar://problem/6268365> 58// 59 60unsigned r6268365Aux(); 61 62void r6268365() { 63 unsigned x = 0; 64 x &= r6268365Aux(); 65 unsigned j = 0; 66 67 if (x == 0) ++j; 68 if (x == 0) x = x / j; // no-warning 69} 70 71void divzeroassume(unsigned x, unsigned j) { 72 x /= j; 73 if (j == 0) x /= 0; // no-warning 74 if (j == 0) x /= j; // no-warning 75 if (j == 0) x = x / 0; // no-warning 76} 77 78void divzeroassumeB(unsigned x, unsigned j) { 79 x = x / j; 80 if (j == 0) x /= 0; // no-warning 81 if (j == 0) x /= j; // no-warning 82 if (j == 0) x = x / 0; // no-warning 83} 84 85// InitListExpr processing 86 87typedef float __m128 __attribute__((__vector_size__(16), __may_alias__)); 88__m128 return128() { 89 // This compound literal has a Vector type. We currently just 90 // return UnknownVal. 91 return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f }; 92} 93 94typedef long long __v2di __attribute__ ((__vector_size__ (16))); 95typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); 96__m128i vec128i(long long __q1, long long __q0) { 97 // This compound literal returns true for both isVectorType() and 98 // isIntegerType(). 99 return __extension__ (__m128i)(__v2di){ __q0, __q1 }; 100} 101 102// Zero-sized VLAs. 103void check_zero_sized_VLA(int x) { 104 if (x) 105 return; 106 107 int vla[x]; // expected-warning{{Variable-length array 'vla' has zero elements (undefined behavior)}} 108} 109 110void check_uninit_sized_VLA() { 111 int x; 112 int vla[x]; // expected-warning{{Variable-length array 'vla' garbage value for array size}} 113} 114 115// sizeof(void) 116// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211 117void handle_sizeof_void(unsigned flag) { 118 int* p = 0; 119 120 if (flag) { 121 if (sizeof(void) == 1) 122 return; 123 // Infeasible. 124 *p = 1; // no-warning 125 } 126 127 void* q; 128 129 if (!flag) { 130 if (sizeof(*q) == 1) 131 return; 132 // Infeasibe. 133 *p = 1; // no-warning 134 } 135 136 // Infeasible. 137 *p = 1; // no-warning 138} 139 140// PR 3422 141void pr3422_helper(char *p); 142void pr3422() { 143 char buf[100]; 144 char *q = &buf[10]; 145 pr3422_helper(&q[1]); 146} 147 148// PR 3543 (handle empty statement expressions) 149int pr_3543(void) { 150 ({}); 151} 152 153// <rdar://problem/6611677> 154// This test case test the use of a vector type within an array subscript 155// expression. 156typedef long long __a64vector __attribute__((__vector_size__(8))); 157typedef long long __a128vector __attribute__((__vector_size__(16))); 158static inline __a64vector __attribute__((__always_inline__, __nodebug__)) 159my_test_mm_movepi64_pi64(__a128vector a) { 160 return (__a64vector)a[0]; 161} 162 163// Test basic tracking of ivars associated with 'self'. 164@interface SelfIvarTest : NSObject { 165 int flag; 166} 167- (void)test_self_tracking; 168@end 169 170@implementation SelfIvarTest 171- (void)test_self_tracking { 172 char *p = 0; 173 char c; 174 175 if (flag) 176 p = "hello"; 177 178 if (flag) 179 c = *p; // no-warning 180} 181@end 182 183// PR 3770 184char pr3770(int x) { 185 int y = x & 0x2; 186 char *p = 0; 187 if (y == 1) 188 p = "hello"; 189 190 if (y == 1) 191 return p[0]; // no-warning 192 193 return 'a'; 194} 195 196// PR 3772 197// - We just want to test that this doesn't crash the analyzer. 198typedef struct st ST; 199struct st { char *name; }; 200extern ST *Cur_Pu; 201 202void pr3772(void) 203{ 204 static ST *last_Cur_Pu; 205 if (last_Cur_Pu == Cur_Pu) { 206 return; 207 } 208} 209 210// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups. 211void pr3780(int sz) { typedef double MAT[sz][sz]; } 212 213// <rdar://problem/6695527> - Test that we don't symbolicate doubles before 214// we are ready to do something with them. 215int rdar6695527(double x) { 216 if (!x) { return 0; } 217 return 1; 218} 219 220// <rdar://problem/6708148> - Test that we properly invalidate structs 221// passed-by-reference to a function. 222void pr6708148_invalidate(NSRect *x); 223void pr6708148_use(NSRect x); 224void pr6708148_test(void) { 225 NSRect x; 226 pr6708148_invalidate(&x); 227 pr6708148_use(x); // no-warning 228} 229 230// Handle both kinds of noreturn attributes for pruning paths. 231void rdar_6777003_noret() __attribute__((noreturn)); 232void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn)); 233 234void rdar_6777003(int x) { 235 int *p = 0; 236 237 if (x == 1) { 238 rdar_6777003_noret(); 239 *p = 1; // no-warning; 240 } 241 242 if (x == 2) { 243 rdar_6777003_analyzer_noret(); 244 *p = 1; // no-warning; 245 } 246 247 *p = 1; // expected-warning{{Dereference of null pointer}} 248} 249 250// For pointer arithmetic, --/++ should be treated as preserving non-nullness, 251// regardless of how well the underlying StoreManager reasons about pointer 252// arithmetic. 253// <rdar://problem/6777209> 254void rdar_6777209(char *p) { 255 if (p == 0) 256 return; 257 258 ++p; 259 260 // This branch should always be infeasible. 261 if (p == 0) 262 *p = 'c'; // no-warning 263} 264 265// PR 4033. A symbolic 'void *' pointer can be used as the address for a 266// computed goto. 267typedef void *Opcode; 268Opcode pr_4033_getOpcode(); 269void pr_4033(void) { 270next_opcode: 271 { 272 Opcode op = pr_4033_getOpcode(); 273 if (op) goto *op; 274 } 275} 276 277// Test invalidating pointers-to-pointers with slightly different types. This 278// example came from a recent false positive due to a regression where the 279// branch condition was falsely reported as being uninitialized. 280void invalidate_by_ref(char **x); 281int test_invalidate_by_ref() { 282 unsigned short y; 283 invalidate_by_ref((char**) &y); 284 if (y) // no-warning 285 return 1; 286 return 0; 287} 288 289// Test for <rdar://problem/7027684>. This just tests that the CFG is 290// constructed correctly. Previously, the successor block of the entrance 291// was the block containing the merge for '?', which would trigger an 292// assertion failure. 293int rdar_7027684_aux(); 294int rdar_7027684_aux_2() __attribute__((noreturn)); 295void rdar_7027684(int x, int y) { 296 {}; // this empty compound statement is critical. 297 (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0); 298} 299 300// Test that we handle casts of string literals to arbitrary types. 301unsigned const char *string_literal_test1() { 302 return (const unsigned char*) "hello"; 303} 304 305const float *string_literal_test2() { 306 return (const float*) "hello"; 307} 308 309// Test that we handle casts *from* incomplete struct types. 310extern const struct _FooAssertStruct _cmd; 311void test_cast_from_incomplete_struct_aux(volatile const void *x); 312void test_cast_from_incomplete_struct() { 313 test_cast_from_incomplete_struct_aux(&_cmd); 314} 315 316// Test for <rdar://problem/7034511> 317// "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' 318// when 'T' is a pointer" 319// 320// Previously this case would crash. 321void test_rdar_7034511(NSArray *y) { 322 NSObject *x; 323 for (x in y) {} 324 if (x == ((void*) 0)) {} 325} 326 327// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer 328// types. This was previously causing a crash in CastRegion. 329void handle_funcptr_voidptr_casts() { 330 void **ptr; 331 typedef void *PVOID; 332 typedef void *PCHAR; 333 typedef long INT_PTR, *PINT_PTR; 334 typedef INT_PTR (*FARPROC)(); 335 FARPROC handle_funcptr_voidptr_casts_aux(); 336 PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x); 337 PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x); 338 339 ptr = (void**) handle_funcptr_voidptr_casts_aux(); 340 handle_funcptr_voidptr_casts_aux_2(ptr); 341 handle_funcptr_voidptr_casts_aux_3(ptr); 342} 343 344// RegionStore::Retrieve previously crashed on this example. This example 345// was previously in the test file 'xfail_regionstore_wine_crash.c'. 346void testA() { 347 long x = 0; 348 char *y = (char *) &x; 349 if (!*y) 350 return; 351} 352 353// RegionStoreManager previously crashed on this example. The problem is that 354// the value bound to the field of b->grue after the call to testB_aux is 355// a symbolic region. The second '*__gruep__' involves performing a load 356// from a 'int*' that really is a 'void**'. The loaded location must be 357// implicitly converted to an integer that wraps a location. Previosly we would 358// get a crash here due to an assertion failure. 359typedef struct _BStruct { void *grue; } BStruct; 360void testB_aux(void *ptr); 361void testB(BStruct *b) { 362 { 363 int *__gruep__ = ((int *)&((b)->grue)); 364 int __gruev__ = *__gruep__; 365 testB_aux(__gruep__); 366 } 367 { 368 int *__gruep__ = ((int *)&((b)->grue)); 369 int __gruev__ = *__gruep__; 370 if (~0 != __gruev__) {} 371 } 372} 373 374void test_trivial_symbolic_comparison(int *x) { 375 int test_trivial_symbolic_comparison_aux(); 376 int a = test_trivial_symbolic_comparison_aux(); 377 int b = a; 378 if (a != b) { 379 int *p = 0; 380 *p = 0xDEADBEEF; // no-warning 381 } 382 383 a = a == 1; 384 b = b == 1; 385 if (a != b) { 386 int *p = 0; 387 *p = 0xDEADBEEF; // no-warning 388 } 389} 390 391