1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,deadcode.DeadStores,osx.cocoa.RetainCount,unix.Malloc,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t -w %s 2// RUN: %normalize_plist <%t | diff -ub %S/Inputs/expected-plists/edges-new.mm.plist - 3 4//===----------------------------------------------------------------------===// 5// Forward declarations (from headers). 6//===----------------------------------------------------------------------===// 7 8typedef const struct __CFNumber * CFNumberRef; 9typedef const struct __CFAllocator * CFAllocatorRef; 10extern const CFAllocatorRef kCFAllocatorDefault; 11typedef signed long CFIndex; 12enum { 13 kCFNumberSInt8Type = 1, 14 kCFNumberSInt16Type = 2, 15 kCFNumberSInt32Type = 3, 16 kCFNumberSInt64Type = 4, 17 kCFNumberFloat32Type = 5, 18 kCFNumberFloat64Type = 6, 19 kCFNumberCharType = 7, 20 kCFNumberShortType = 8, 21 kCFNumberIntType = 9, 22 kCFNumberLongType = 10, 23 kCFNumberLongLongType = 11, 24 kCFNumberFloatType = 12, 25 kCFNumberDoubleType = 13, 26 kCFNumberCFIndexType = 14, 27 kCFNumberNSIntegerType = 15, 28 kCFNumberCGFloatType = 16, 29 kCFNumberMaxType = 16 30}; 31typedef CFIndex CFNumberType; 32CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); 33 34#define nil ((id)0) 35 36__attribute__((objc_root_class)) 37@interface NSObject 38+ (instancetype) alloc; 39- (instancetype) init; 40- (instancetype)retain; 41- (void)release; 42@end 43 44@interface NSArray : NSObject 45@end 46 47//===----------------------------------------------------------------------===// 48// Basic tracking of null and tests for null. 49//===----------------------------------------------------------------------===// 50 51void test_null_init(void) { 52 int *p = 0; 53 *p = 0xDEADBEEF; 54} 55 56void test_null_assign(void) { 57 int *p; 58 p = 0; 59 *p = 0xDEADBEEF; 60} 61 62void test_null_assign_transitive(void) { 63 int *p; 64 p = 0; 65 int *q = p; 66 *q = 0xDEADBEEF; 67} 68 69void test_null_cond(int *p) { 70 if (!p) { 71 *p = 0xDEADBEEF; 72 } 73} 74 75void test_null_cond_transitive(int *q) { 76 if (!q) { 77 int *p = q; 78 *p = 0xDEADBEEF; 79 } 80} 81 82void test_null_field(void) { 83 struct s { int *p; } x; 84 x.p = 0; 85 *(x.p) = 0xDEADBEEF; 86} 87 88void test_assumptions(int a, int b) 89{ 90 if (a == 0) { 91 return; 92 } 93 if (b != 0) { 94 return; 95 } 96 int *p = 0; 97 *p = 0xDEADBEEF; 98} 99 100int *bar_cond_assign(); 101int test_cond_assign() { 102 int *p; 103 if ((p = bar_cond_assign())) 104 return 1; 105 return *p; 106} 107 108//===----------------------------------------------------------------------===// 109// Diagnostics for leaks and "noreturn" paths. 110//===----------------------------------------------------------------------===// 111 112 113// <rdar://problem/8331641> leak reports should not show paths that end with exit() (but ones that don't end with exit()) 114 115void stop() __attribute__((noreturn)); 116 117void rdar8331641(int x) { 118 signed z = 1; 119 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} 120 if (x) 121 stop(); 122 (void) value; 123} 124 125//===----------------------------------------------------------------------===// 126// Test loops and control-flow. 127//===----------------------------------------------------------------------===// 128 129void test_objc_fast_enumeration(NSArray *x) { 130 id obj; 131 for (obj in x) 132 *(volatile int *)0 = 0; 133} 134 135void test_objc_fast_enumeration_2(id arr) { 136 int x; 137 for (id obj in arr) { 138 x = 1; 139 } 140 x += 1; 141} 142 143// Test that loops are documented in the path. 144void rdar12280665() { 145 for (unsigned i = 0; i < 2; ++i) { 146 if (i == 1) { 147 int *p = 0; 148 *p = 0xDEADBEEF; // expected-warning {{dereference}} 149 } 150 } 151} 152 153// Test for a "loop executed 0 times" diagnostic. 154int *radar12322528_bar(); 155 156void radar12322528_for(int x) { 157 int z; 158 int *p = 0; 159 for (unsigned i = 0; i < x; ++i) { 160 p = radar12322528_bar(); 161 } 162 *p = 0xDEADBEEF; 163} 164 165void radar12322528_while(int x) { 166 int *p = 0; 167 unsigned i = 0; 168 for ( ; i < x ; ) { 169 ++i; 170 p = radar12322528_bar(); 171 } 172 *p = 0xDEADBEEF; 173} 174 175void radar12322528_foo_2() { 176 int *p = 0; 177 for (unsigned i = 0; i < 2; ++i) { 178 if (i == 0) 179 continue; 180 181 if (i == 1) { 182 183 break; 184 } 185 } 186 *p = 0xDEADBEEF; 187} 188 189void test_loop_diagnostics() { 190 int *p = 0; 191 for (int i = 0; i < 2; ++i) { p = 0; } 192 *p = 1; 193} 194 195void test_loop_diagnostics_2() { 196 int *p = 0; 197 198 for (int i = 0; i < 2; ) { 199 200 ++i; 201 202 p = 0; 203 204 } 205 206 *p = 1; 207} 208 209void test_loop_diagnostics_3() { 210 int z; 211 int y; 212 int k; 213 int *p = 0; 214 int i = 0; 215 while (i < 2) { 216 ++i; 217 p = 0; 218 } 219 * p = 1; 220} 221 222void test_do_while() { 223 unsigned i = 0; 224 225 int *p; 226 227 do { 228 229 ++i; 230 p = 0; 231 232 } while (i< 2); 233 234 *p = 0xDEADBEEF; 235} 236 237 238void test_logical_and() { 239 int *p = 0; 240 if (1 && 2) { 241 *p = 0xDEADBEEF; 242 } 243} 244 245void test_logical_or() { 246 int *p = 0; 247 if (0 || 2) { 248 *p = 0xDEADBEEF; 249 } 250} 251 252void test_logical_or_call() { 253 extern int call(int); 254 int *p = 0; 255 if (call(0 || 2)) { 256 *p = 0xDEADBEEF; 257 } 258} 259 260void test_nested_logicals(int coin) { 261 int *p = 0; 262 263 if ((0 || 0) || coin) { 264 *p = 0xDEADBEEF; 265 } 266 267 if (0 || (0 || !coin)) { 268 *p = 0xDEADBEEF; 269 } 270} 271 272void test_deeply_nested_logicals() { 273 extern int call(int); 274 int *p = 0; 275 276 if ((0 || (5 && 0)) ? 0 : ((0 || 4) ? call(1 && 5) : 0)) { 277 278 *p = 0xDEADBEEF; 279 } 280} 281 282void test_ternary(int x, int *y) { 283 int z = x ? 0 : 1; 284 285 int *p = z ? y : 0; 286 287 *p = 0xDEADBEEF; 288} 289 290void testUseless(int *y) { 291 if (y) { 292 293 } 294 if (y) { 295 296 } 297 int *p = 0; 298 *p = 0xDEADBEEF; 299} 300 301//===----------------------------------------------------------------------===// 302// Interprocedural tests. 303//===----------------------------------------------------------------------===// 304 305@interface IPA_Foo 306- (int *) returnsPointer; 307@end 308 309int testFoo(IPA_Foo *x) { 310 if (x) 311 return 1; 312 return *[x returnsPointer]; 313} 314 315@interface IPA_X : NSObject 316- (int *)getPointer; 317@end 318 319void test1_IPA_X() { 320 IPA_X *x = nil; 321 *[x getPointer] = 1; // here 322} 323 324 325@interface IPA_Y : NSObject 326- (IPA_Y *)opaque; 327- (IPA_X *)getX; 328@end 329 330@implementation IPA_Y 331- (IPA_X *)getX { 332 return nil; 333} 334@end 335 336void test_IPA_Y(IPA_Y *y) { 337 if (y) 338 return; 339 340 IPA_X *x = [[y opaque] getX]; // here 341 *[x getPointer] = 1; 342} 343 344// From diagnostics/report-issues-within-main-file.cpp: 345void causeDivByZeroInMain(int in) { 346 int m = 0; 347 m = in/m; 348 m++; 349} 350 351void mainPlusMain() { 352 int i = 0; 353 i++; 354 causeDivByZeroInMain(i); 355 i++; 356} 357 358// From inlining/path-notes.c: 359int *getZero() { 360 int *p = 0; 361 return p; 362} 363 364void usePointer(int *p) { 365 *p = 1; 366} 367 368void testUseOfNullPointer() { 369 // Test the case where an argument expression is itself a call. 370 usePointer(getZero()); 371} 372 373 374//===----------------------------------------------------------------------===// 375// Misc. tests. 376//===----------------------------------------------------------------------===// 377 378// Test for tracking null state of ivars. 379@interface RDar12114812 : NSObject { char *p; } 380@end 381@implementation RDar12114812 382- (void)test { 383 p = 0; 384 *p = 1; 385} 386@end 387 388// Test diagnostics for initialization of structs. 389void RDar13295437_f(void *i) __attribute__((__nonnull__)); 390struct RDar13295437_S { int *i; }; 391int RDar13295437() { 392 struct RDar13295437_S s = {0}; 393 struct RDar13295437_S *sp = &s; 394 RDar13295437_f(sp->i); 395 return 0; 396} 397 398 399void testCast(int coin) { 400 if (coin) { 401 (void)(1+2); 402 (void)(2+3); 403 (void)(3+4); 404 *(volatile int *)0 = 1; 405 } 406} 407 408// The following previously crashed when generating extensive diagnostics. 409// <rdar://problem/10797980> 410@interface RDar10797980_help 411@property (readonly) int x; 412@end 413@interface RDar10797980 : NSObject { 414 RDar10797980_help *y; 415} 416- (void) test; 417@end 418@implementation RDar10797980 419- (void) test { 420 if (y.x == 1) { 421 int *p = 0; 422 *p = 0xDEADBEEF; // expected-warning {{deference}} 423 } 424} 425 426// The original source for the above Radar contains another problem: 427// if the end-of-path node is an implicit statement, it may not have a valid 428// source location. <rdar://problem/12446776> 429- (void)test2 { 430 if (bar_cond_assign()) { 431 id foo = [[RDar10797980 alloc] init]; // leak 432 } 433 (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr 434} 435 436@end 437 438void variousLoops(id input) { 439 extern int a(); 440 extern int b(); 441 extern int c(); 442 443 extern int work(); 444 445 while (a()) { 446 work(); 447 work(); 448 work(); 449 *(volatile int *)0 = 1; 450 } 451 452 int first = 1; 453 do { 454 work(); 455 work(); 456 work(); 457 if (!first) 458 *(volatile int *)0 = 1; 459 first = 0; 460 } while (a()); 461 462 for (int i = 0; i != b(); ++i) { 463 work(); 464 *(volatile int *)0 = 1; 465 } 466 467 for (id x in input) { 468 work(); 469 work(); 470 work(); 471 (void)x; 472 *(volatile int *)0 = 1; 473 } 474 475 int z[] = {1,2}; 476 for (int y : z) { 477 work(); 478 work(); 479 work(); 480 (void)y; 481 } 482 483 int empty[] = {}; 484 for (int y : empty) { 485 work(); 486 work(); 487 work(); 488 (void)y; 489 } 490 491 for (int i = 0; ; ++i) { 492 work(); 493 if (i == b()) 494 break; 495 } 496 497 int i; 498 for (i = 0; i != b(); ++i) { 499 work(); 500 *(volatile int *)0 = 1; 501 } 502 503 for (; i != b(); ++i) { 504 work(); 505 *(volatile int *)0 = 1; 506 } 507 508 for (; i != b(); ) { 509 work(); 510 if (i == b()) 511 break; 512 *(volatile int *)0 = 1; 513 } 514 515 for (;;) { 516 work(); 517 if (i == b()) 518 break; 519 } 520 521 *(volatile int *)0 = 1; 522} 523 524void *malloc(unsigned long); 525void *realloc(void *, unsigned long); 526void free(void *); 527 528void reallocDiagnostics() { 529 char * buf = (char*)malloc(100); 530 char * tmp; 531 tmp = (char*)realloc(buf, 0x1000000); 532 if (!tmp) { 533 return;// expected-warning {{leak}} 534 } 535 buf = tmp; 536 free(buf); 537} 538 539template <typename T> 540class unique_ptr { 541 T *ptr; 542public: 543 explicit unique_ptr(T *p) : ptr(p) {} 544 ~unique_ptr() { delete ptr; } 545}; 546 547void test() { 548 int i = 0; 549 ++i; 550 551 unique_ptr<int> p(new int[4]); 552 { 553 ++i; 554 } 555} 556 557void longLines() { 558 id foo = [[NSObject alloc] init]; // leak 559 id bar = 560 [foo retain]; 561 [bar release]; 562 id baz = [foo 563 retain]; 564 [baz release]; 565 // This next line is intentionally longer than 80 characters. 566 id garply = [foo retain]; 567 [garply release]; 568} 569 570#define POINTER(T) T* 571POINTER(void) testMacroInFunctionDecl(void *q) { 572 int *p = 0; 573 *p = 1; 574 return q; 575} 576 577namespace rdar14960554 { 578 class Foo { 579 int a = 1; 580 int b = 2; 581 int c = 3; 582 583 Foo() : 584 a(0), 585 c(3) { 586 // Check that we don't have an edge to the in-class initializer for 'b'. 587 if (b == 2) 588 *(volatile int *)0 = 1; 589 } 590 }; 591} 592 593