misc-ps.m revision ab2f43cfe7272d77374d8dec8f9df625bf525468
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 -analyzer-constraints=range --verify -fblocks %s && 3// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && 4// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s 5 6typedef struct objc_ivar *Ivar; 7typedef struct objc_selector *SEL; 8typedef signed char BOOL; 9typedef int NSInteger; 10typedef unsigned int NSUInteger; 11typedef struct _NSZone NSZone; 12@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator; 13@protocol NSObject 14- (BOOL)isEqual:(id)object; 15- (id)autorelease; 16@end 17@protocol NSCopying 18- (id)copyWithZone:(NSZone *)zone; 19@end 20@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end 21@protocol NSCoding 22- (void)encodeWithCoder:(NSCoder *)aCoder; 23@end 24@interface NSObject <NSObject> {} 25- (id)init; 26+ (id)allocWithZone:(NSZone *)zone; 27@end 28extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 29@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> 30- (NSUInteger)length; 31+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; 32@end extern NSString * const NSBundleDidLoadNotification; 33@interface NSValue : NSObject <NSCopying, NSCoding> 34- (void)getValue:(void *)value; 35@end 36@interface NSNumber : NSValue 37- (char)charValue; 38- (id)initWithBool:(BOOL)value; 39@end 40@interface NSAssertionHandler : NSObject {} 41+ (NSAssertionHandler *)currentHandler; 42- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; 43@end 44extern NSString * const NSConnectionReplyMode; 45typedef float CGFloat; 46typedef struct _NSPoint { 47 CGFloat x; 48 CGFloat y; 49} NSPoint; 50typedef struct _NSSize { 51 CGFloat width; 52 CGFloat height; 53} NSSize; 54typedef struct _NSRect { 55 NSPoint origin; 56 NSSize size; 57} NSRect; 58 59// Reduced test case from crash in <rdar://problem/6253157> 60@interface A @end 61@implementation A 62- (void)foo:(void (^)(NSObject *x))block { 63 if (!((block != ((void *)0)))) {} 64} 65@end 66 67// Reduced test case from crash in PR 2796; 68// http://llvm.org/bugs/show_bug.cgi?id=2796 69 70unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); } 71 72// Improvement to path-sensitivity involving compound assignments. 73// Addresses false positive in <rdar://problem/6268365> 74// 75 76unsigned r6268365Aux(); 77 78void r6268365() { 79 unsigned x = 0; 80 x &= r6268365Aux(); 81 unsigned j = 0; 82 83 if (x == 0) ++j; 84 if (x == 0) x = x / j; // no-warning 85} 86 87void divzeroassume(unsigned x, unsigned j) { 88 x /= j; 89 if (j == 0) x /= 0; // no-warning 90 if (j == 0) x /= j; // no-warning 91 if (j == 0) x = x / 0; // no-warning 92} 93 94void divzeroassumeB(unsigned x, unsigned j) { 95 x = x / j; 96 if (j == 0) x /= 0; // no-warning 97 if (j == 0) x /= j; // no-warning 98 if (j == 0) x = x / 0; // no-warning 99} 100 101// InitListExpr processing 102 103typedef float __m128 __attribute__((__vector_size__(16), __may_alias__)); 104__m128 return128() { 105 // This compound literal has a Vector type. We currently just 106 // return UnknownVal. 107 return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f }; 108} 109 110typedef long long __v2di __attribute__ ((__vector_size__ (16))); 111typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); 112__m128i vec128i(long long __q1, long long __q0) { 113 // This compound literal returns true for both isVectorType() and 114 // isIntegerType(). 115 return __extension__ (__m128i)(__v2di){ __q0, __q1 }; 116} 117 118// Zero-sized VLAs. 119void check_zero_sized_VLA(int x) { 120 if (x) 121 return; 122 123 int vla[x]; // expected-warning{{Variable-length array 'vla' has zero elements (undefined behavior)}} 124} 125 126void check_uninit_sized_VLA() { 127 int x; 128 int vla[x]; // expected-warning{{Variable-length array 'vla' garbage value for array size}} 129} 130 131// sizeof(void) 132// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211 133void handle_sizeof_void(unsigned flag) { 134 int* p = 0; 135 136 if (flag) { 137 if (sizeof(void) == 1) 138 return; 139 // Infeasible. 140 *p = 1; // no-warning 141 } 142 143 void* q; 144 145 if (!flag) { 146 if (sizeof(*q) == 1) 147 return; 148 // Infeasibe. 149 *p = 1; // no-warning 150 } 151 152 // Infeasible. 153 *p = 1; // no-warning 154} 155 156// PR 3422 157void pr3422_helper(char *p); 158void pr3422() { 159 char buf[100]; 160 char *q = &buf[10]; 161 pr3422_helper(&q[1]); 162} 163 164// PR 3543 (handle empty statement expressions) 165void pr_3543(void) { 166 ({}); 167} 168 169// <rdar://problem/6611677> 170// This test case test the use of a vector type within an array subscript 171// expression. 172typedef long long __a64vector __attribute__((__vector_size__(8))); 173typedef long long __a128vector __attribute__((__vector_size__(16))); 174static inline __a64vector __attribute__((__always_inline__, __nodebug__)) 175my_test_mm_movepi64_pi64(__a128vector a) { 176 return (__a64vector)a[0]; 177} 178 179// Test basic tracking of ivars associated with 'self'. 180@interface SelfIvarTest : NSObject { 181 int flag; 182} 183- (void)test_self_tracking; 184@end 185 186@implementation SelfIvarTest 187- (void)test_self_tracking { 188 char *p = 0; 189 char c; 190 191 if (flag) 192 p = "hello"; 193 194 if (flag) 195 c = *p; // no-warning 196} 197@end 198 199// PR 3770 200char pr3770(int x) { 201 int y = x & 0x2; 202 char *p = 0; 203 if (y == 1) 204 p = "hello"; 205 206 if (y == 1) 207 return p[0]; // no-warning 208 209 return 'a'; 210} 211 212// PR 3772 213// - We just want to test that this doesn't crash the analyzer. 214typedef struct st ST; 215struct st { char *name; }; 216extern ST *Cur_Pu; 217 218void pr3772(void) 219{ 220 static ST *last_Cur_Pu; 221 if (last_Cur_Pu == Cur_Pu) { 222 return; 223 } 224} 225 226// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups. 227void pr3780(int sz) { typedef double MAT[sz][sz]; } 228 229// <rdar://problem/6695527> - Test that we don't symbolicate doubles before 230// we are ready to do something with them. 231int rdar6695527(double x) { 232 if (!x) { return 0; } 233 return 1; 234} 235 236// <rdar://problem/6708148> - Test that we properly invalidate structs 237// passed-by-reference to a function. 238void pr6708148_invalidate(NSRect *x); 239void pr6708148_use(NSRect x); 240void pr6708148_test(void) { 241 NSRect x; 242 pr6708148_invalidate(&x); 243 pr6708148_use(x); // no-warning 244} 245 246// Handle both kinds of noreturn attributes for pruning paths. 247void rdar_6777003_noret() __attribute__((noreturn)); 248void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn)); 249 250void rdar_6777003(int x) { 251 int *p = 0; 252 253 if (x == 1) { 254 rdar_6777003_noret(); 255 *p = 1; // no-warning; 256 } 257 258 if (x == 2) { 259 rdar_6777003_analyzer_noret(); 260 *p = 1; // no-warning; 261 } 262 263 *p = 1; // expected-warning{{Dereference of null pointer}} 264} 265 266// For pointer arithmetic, --/++ should be treated as preserving non-nullness, 267// regardless of how well the underlying StoreManager reasons about pointer 268// arithmetic. 269// <rdar://problem/6777209> 270void rdar_6777209(char *p) { 271 if (p == 0) 272 return; 273 274 ++p; 275 276 // This branch should always be infeasible. 277 if (p == 0) 278 *p = 'c'; // no-warning 279} 280 281// PR 4033. A symbolic 'void *' pointer can be used as the address for a 282// computed goto. 283typedef void *Opcode; 284Opcode pr_4033_getOpcode(); 285void pr_4033(void) { 286next_opcode: 287 { 288 Opcode op = pr_4033_getOpcode(); 289 if (op) goto *op; 290 } 291} 292 293// Test invalidating pointers-to-pointers with slightly different types. This 294// example came from a recent false positive due to a regression where the 295// branch condition was falsely reported as being uninitialized. 296void invalidate_by_ref(char **x); 297int test_invalidate_by_ref() { 298 unsigned short y; 299 invalidate_by_ref((char**) &y); 300 if (y) // no-warning 301 return 1; 302 return 0; 303} 304 305// Test for <rdar://problem/7027684>. This just tests that the CFG is 306// constructed correctly. Previously, the successor block of the entrance 307// was the block containing the merge for '?', which would trigger an 308// assertion failure. 309int rdar_7027684_aux(); 310int rdar_7027684_aux_2() __attribute__((noreturn)); 311void rdar_7027684(int x, int y) { 312 {}; // this empty compound statement is critical. 313 (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0); 314} 315 316// Test that we handle casts of string literals to arbitrary types. 317unsigned const char *string_literal_test1() { 318 return (const unsigned char*) "hello"; 319} 320 321const float *string_literal_test2() { 322 return (const float*) "hello"; 323} 324 325// Test that we handle casts *from* incomplete struct types. 326extern const struct _FooAssertStruct _cmd; 327void test_cast_from_incomplete_struct_aux(volatile const void *x); 328void test_cast_from_incomplete_struct() { 329 test_cast_from_incomplete_struct_aux(&_cmd); 330} 331 332// Test for <rdar://problem/7034511> 333// "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' 334// when 'T' is a pointer" 335// 336// Previously this case would crash. 337void test_rdar_7034511(NSArray *y) { 338 NSObject *x; 339 for (x in y) {} 340 if (x == ((void*) 0)) {} 341} 342 343// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer 344// types. This was previously causing a crash in CastRegion. 345void handle_funcptr_voidptr_casts() { 346 void **ptr; 347 typedef void *PVOID; 348 typedef void *PCHAR; 349 typedef long INT_PTR, *PINT_PTR; 350 typedef INT_PTR (*FARPROC)(); 351 FARPROC handle_funcptr_voidptr_casts_aux(); 352 PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x); 353 PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x); 354 355 ptr = (void**) handle_funcptr_voidptr_casts_aux(); 356 handle_funcptr_voidptr_casts_aux_2(ptr); 357 handle_funcptr_voidptr_casts_aux_3(ptr); 358} 359 360// RegionStore::Retrieve previously crashed on this example. This example 361// was previously in the test file 'xfail_regionstore_wine_crash.c'. 362void testA() { 363 long x = 0; 364 char *y = (char *) &x; 365 if (!*y) 366 return; 367} 368 369// RegionStoreManager previously crashed on this example. The problem is that 370// the value bound to the field of b->grue after the call to testB_aux is 371// a symbolic region. The second '*__gruep__' involves performing a load 372// from a 'int*' that really is a 'void**'. The loaded location must be 373// implicitly converted to an integer that wraps a location. Previosly we would 374// get a crash here due to an assertion failure. 375typedef struct _BStruct { void *grue; } BStruct; 376void testB_aux(void *ptr); 377void testB(BStruct *b) { 378 { 379 int *__gruep__ = ((int *)&((b)->grue)); 380 int __gruev__ = *__gruep__; 381 testB_aux(__gruep__); 382 } 383 { 384 int *__gruep__ = ((int *)&((b)->grue)); 385 int __gruev__ = *__gruep__; 386 if (~0 != __gruev__) {} 387 } 388} 389 390void test_trivial_symbolic_comparison(int *x) { 391 int test_trivial_symbolic_comparison_aux(); 392 int a = test_trivial_symbolic_comparison_aux(); 393 int b = a; 394 if (a != b) { 395 int *p = 0; 396 *p = 0xDEADBEEF; // no-warning 397 } 398 399 a = a == 1; 400 b = b == 1; 401 if (a != b) { 402 int *p = 0; 403 *p = 0xDEADBEEF; // no-warning 404 } 405} 406 407// Test for: 408// <rdar://problem/7062158> false positive null dereference due to 409// BasicStoreManager not tracking *static* globals 410// 411// This just tests the proper tracking of symbolic values for globals (both 412// static and non-static). 413// 414static int* x_rdar_7062158; 415void rdar_7062158() { 416 int *current = x_rdar_7062158; 417 if (current == x_rdar_7062158) 418 return; 419 420 int *p = 0; 421 *p = 0xDEADBEEF; // no-warning 422} 423 424int* x_rdar_7062158_2; 425void rdar_7062158_2() { 426 int *current = x_rdar_7062158_2; 427 if (current == x_rdar_7062158_2) 428 return; 429 430 int *p = 0; 431 *p = 0xDEADBEEF; // no-warning 432} 433 434// This test reproduces a case for a crash when analyzing ClamAV using 435// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because 436// it isn't doing anything smart about arrays). The problem is that on the 437// second line, 'p = &p[i]', p is assigned an ElementRegion whose index 438// is a 16-bit integer. On the third line, a new ElementRegion is created 439// based on the previous region, but there the region uses a 32-bit integer, 440// resulting in a clash of values (an assertion failure at best). We resolve 441// this problem by implicitly converting index values to 'int' when the 442// ElementRegion is created. 443unsigned char test_array_index_bitwidth(const unsigned char *p) { 444 unsigned short i = 0; 445 for (i = 0; i < 2; i++) p = &p[i]; 446 return p[i+1]; 447} 448 449// This case tests that CastRegion handles casts involving BlockPointerTypes. 450// It should not crash. 451void test_block_cast() { 452 id test_block_cast_aux(); 453 (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}} 454} 455 456// Test comparison of 'id' instance variable to a null void* constant after 457// performing an OSAtomicCompareAndSwap32Barrier. 458// This previously was a crash in RegionStoreManager. 459@interface TestIdNull { 460 id x; 461} 462-(int)foo; 463@end 464@implementation TestIdNull 465-(int)foo { 466 OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x); 467 if (x == (void*) 0) { return 0; } 468 return 1; 469} 470@end 471 472// PR 4594 - This was a crash when handling casts in SimpleSValuator. 473void PR4594() { 474 char *buf[1]; 475 char **foo = buf; 476 *foo = "test"; 477} 478 479// Test invalidation logic where an integer is casted to an array with a 480// different sign and then invalidated. 481void test_invalidate_cast_int() { 482 void test_invalidate_cast_int_aux(unsigned *i); 483 signed i; 484 test_invalidate_cast_int_aux((unsigned*) &i); 485 if (i < 0) 486 return; 487} 488 489// Reduced from a crash involving the cast of an Objective-C symbolic region to 490// 'char *' 491static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) { 492 return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease]; 493} 494 495// Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero. 496// This resulted from not properly handling region casts to 'const void*'. 497void test_cast_const_voidptr() { 498 char x[10]; 499 char *p = &x[1]; 500 const void* q = p; 501} 502 503// Reduced from a crash when analyzing Wine. This test handles loads from 504// function addresses. 505typedef long (*FARPROC)(); 506FARPROC test_load_func(FARPROC origfun) { 507 if (!*(unsigned char*) origfun) 508 return origfun; 509 return 0; 510} 511 512// Test passing-by-value an initialized struct variable. 513struct test_pass_val { 514 int x; 515 int y; 516}; 517void test_pass_val_aux(struct test_pass_val s); 518void test_pass_val() { 519 struct test_pass_val s; 520 s.x = 1; 521 s.y = 2; 522 test_pass_val_aux(s); 523} 524 525// This is a reduced test case of a false positive that previously appeared 526// in RegionStoreManager. Previously the array access resulted in dereferencing 527// an undefined value. 528int test_array_compound(int *q, int *r, int *z) { 529 int *array[] = { q, r, z }; 530 int j = 0; 531 for (unsigned i = 0; i < 3 ; ++i) 532 if (*array[i]) ++j; // no-warning 533 return j; 534} 535 536// This test case previously crashed with -analyzer-store=basic because the 537// symbolic value stored in 'x' wouldn't be implicitly casted to a signed value 538// during the comparison. 539int rdar_7124210(unsigned int x) { 540 enum { SOME_CONSTANT = 123 }; 541 int compare = ((signed) SOME_CONSTANT) == *((signed *) &x); 542 return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint. 543} 544 545void pr4781(unsigned long *raw1) { 546 unsigned long *cook, *raw0; 547 unsigned long dough[32]; 548 int i; 549 cook = dough; 550 for( i = 0; i < 16; i++, raw1++ ) { 551 raw0 = raw1++; 552 *cook = (*raw0 & 0x00fc0000L) << 6; 553 *cook |= (*raw0 & 0x00000fc0L) << 10; 554 } 555} 556 557