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