592 lines · plain
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 %s2// 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 = 1630};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 NSObject38+ (instancetype) alloc;39- (instancetype) init;40- (instancetype)retain;41- (void)release;42@end43 44@interface NSArray : NSObject45@end46 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// 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_Foo306- (int *) returnsPointer;307@end308 309int testFoo(IPA_Foo *x) {310 if (x)311 return 1;312 return *[x returnsPointer];313}314 315@interface IPA_X : NSObject316- (int *)getPointer;317@end318 319void test1_IPA_X() {320 IPA_X *x = nil;321 *[x getPointer] = 1; // here322}323 324 325@interface IPA_Y : NSObject326- (IPA_Y *)opaque;327- (IPA_X *)getX;328@end329 330@implementation IPA_Y331- (IPA_X *)getX {332 return nil;333}334@end335 336void test_IPA_Y(IPA_Y *y) {337 if (y)338 return;339 340 IPA_X *x = [[y opaque] getX]; // here341 *[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@end381@implementation RDar12114812382- (void)test {383 p = 0;384 *p = 1;385}386@end387 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@interface RDar10797980_help410@property (readonly) int x;411@end412@interface RDar10797980 : NSObject {413 RDar10797980_help *y;414}415- (void) test;416@end417@implementation RDar10797980418- (void) test {419 if (y.x == 1) {420 int *p = 0;421 *p = 0xDEADBEEF; // expected-warning {{deference}}422 }423}424 425// The original source for the above Radar contains another problem:426// if the end-of-path node is an implicit statement, it may not have a valid427// source location.428- (void)test2 {429 if (bar_cond_assign()) {430 id foo = [[RDar10797980 alloc] init]; // leak431 }432 (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr433}434 435@end436 437void variousLoops(id input) {438 extern int a();439 extern int b();440 extern int c();441 442 extern int work();443 444 while (a()) {445 work();446 work();447 work();448 *(volatile int *)0 = 1;449 }450 451 int first = 1;452 do {453 work();454 work();455 work();456 if (!first)457 *(volatile int *)0 = 1;458 first = 0;459 } while (a());460 461 for (int i = 0; i != b(); ++i) {462 work();463 *(volatile int *)0 = 1;464 }465 466 for (id x in input) {467 work();468 work();469 work();470 (void)x;471 *(volatile int *)0 = 1;472 }473 474 int z[] = {1,2};475 for (int y : z) {476 work();477 work();478 work();479 (void)y;480 }481 482 int empty[] = {};483 for (int y : empty) {484 work();485 work();486 work();487 (void)y;488 }489 490 for (int i = 0; ; ++i) {491 work();492 if (i == b())493 break;494 }495 496 int i;497 for (i = 0; i != b(); ++i) {498 work();499 *(volatile int *)0 = 1;500 }501 502 for (; i != b(); ++i) {503 work();504 *(volatile int *)0 = 1;505 }506 507 for (; i != b(); ) {508 work();509 if (i == b())510 break;511 *(volatile int *)0 = 1;512 }513 514 for (;;) {515 work();516 if (i == b())517 break;518 }519 520 *(volatile int *)0 = 1;521}522 523void *malloc(unsigned long);524void *realloc(void *, unsigned long);525void free(void *);526 527void reallocDiagnostics() {528 char * buf = (char*)malloc(100);529 char * tmp;530 tmp = (char*)realloc(buf, 0x1000000);531 if (!tmp) {532 return;// expected-warning {{leak}}533 }534 buf = tmp;535 free(buf);536}537 538template <typename T>539class unique_ptr {540 T *ptr;541public:542 explicit unique_ptr(T *p) : ptr(p) {}543 ~unique_ptr() { delete ptr; }544};545 546void test() {547 int i = 0;548 ++i;549 550 unique_ptr<int> p(new int[4]);551 {552 ++i;553 }554}555 556void longLines() {557 id foo = [[NSObject alloc] init]; // leak558 id bar =559 [foo retain];560 [bar release];561 id baz = [foo562 retain];563 [baz release];564 // This next line is intentionally longer than 80 characters.565 id garply = [foo retain];566 [garply release];567}568 569#define POINTER(T) T*570POINTER(void) testMacroInFunctionDecl(void *q) {571 int *p = 0;572 *p = 1;573 return q;574}575 576namespace rdar14960554 {577 class Foo {578 int a = 1;579 int b = 2;580 int c = 3;581 582 Foo() :583 a(0),584 c(3) {585 // Check that we don't have an edge to the in-class initializer for 'b'.586 if (b == 2)587 *(volatile int *)0 = 1;588 }589 };590}591 592