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