1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -analyzer-store=region -fblocks -verify %s 2*f4a2713aSLionel Sambuc #define NULL 0 3*f4a2713aSLionel Sambuc void clang_analyzer_eval(int); 4*f4a2713aSLionel Sambuc void myFunc(); 5*f4a2713aSLionel Sambuc void myWeakFunc() __attribute__((weak_import)); 6*f4a2713aSLionel Sambuc 7*f4a2713aSLionel Sambuc void testWeakFuncIsNull() 8*f4a2713aSLionel Sambuc { 9*f4a2713aSLionel Sambuc clang_analyzer_eval(myFunc == NULL); // expected-warning{{FALSE}} 10*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{UNKNOWN}} 11*f4a2713aSLionel Sambuc if (myWeakFunc == NULL) { 12*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{TRUE}} 13*f4a2713aSLionel Sambuc } else { 14*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{FALSE}} 15*f4a2713aSLionel Sambuc } 16*f4a2713aSLionel Sambuc } 17*f4a2713aSLionel Sambuc 18*f4a2713aSLionel Sambuc void testWeakFuncIsNot() 19*f4a2713aSLionel Sambuc { 20*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{UNKNOWN}} 21*f4a2713aSLionel Sambuc if (!myWeakFunc) { 22*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{TRUE}} 23*f4a2713aSLionel Sambuc } else { 24*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{FALSE}} 25*f4a2713aSLionel Sambuc } 26*f4a2713aSLionel Sambuc } 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc void testWeakFuncIsTrue() 29*f4a2713aSLionel Sambuc { 30*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{UNKNOWN}} 31*f4a2713aSLionel Sambuc if (myWeakFunc) { 32*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{FALSE}} 33*f4a2713aSLionel Sambuc } else { 34*f4a2713aSLionel Sambuc clang_analyzer_eval(myWeakFunc == NULL); // expected-warning{{TRUE}} 35*f4a2713aSLionel Sambuc } 36*f4a2713aSLionel Sambuc } 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 39*f4a2713aSLionel Sambuc // func.c 40*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 41*f4a2713aSLionel Sambuc void f(void) __attribute__((weak_import)); 42*f4a2713aSLionel Sambuc void g(void (*fp)(void)) __attribute__((weak_import)); 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc void f(void) { 45*f4a2713aSLionel Sambuc void (*p)(void); 46*f4a2713aSLionel Sambuc p = f; 47*f4a2713aSLionel Sambuc p = &f; 48*f4a2713aSLionel Sambuc p(); 49*f4a2713aSLionel Sambuc (*p)(); 50*f4a2713aSLionel Sambuc } 51*f4a2713aSLionel Sambuc 52*f4a2713aSLionel Sambuc void g(void (*fp)(void)); 53*f4a2713aSLionel Sambuc 54*f4a2713aSLionel Sambuc void f2() { 55*f4a2713aSLionel Sambuc g(f); 56*f4a2713aSLionel Sambuc } 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc void f3(void (*f)(void), void (*g)(void)) { 59*f4a2713aSLionel Sambuc clang_analyzer_eval(!f); // expected-warning{{UNKNOWN}} 60*f4a2713aSLionel Sambuc f(); 61*f4a2713aSLionel Sambuc clang_analyzer_eval(!f); // expected-warning{{FALSE}} 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc clang_analyzer_eval(!g); // expected-warning{{UNKNOWN}} 64*f4a2713aSLionel Sambuc (*g)(); 65*f4a2713aSLionel Sambuc clang_analyzer_eval(!g); // expected-warning{{FALSE}} 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 69*f4a2713aSLionel Sambuc // free.c 70*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 71*f4a2713aSLionel Sambuc void free(void *) __attribute__((weak_import)); 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc void t10 () { 74*f4a2713aSLionel Sambuc free((void*)&t10); // expected-warning {{Argument to free() is the address of the function 't10', which is not memory allocated by malloc()}} 75*f4a2713aSLionel Sambuc } 76*f4a2713aSLionel Sambuc 77*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 78*f4a2713aSLionel Sambuc // string.c : strnlen() 79*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 80*f4a2713aSLionel Sambuc typedef typeof(sizeof(int)) size_t; 81*f4a2713aSLionel Sambuc size_t strlen(const char *s) __attribute__((weak_import)); 82*f4a2713aSLionel Sambuc 83*f4a2713aSLionel Sambuc size_t strlen_fn() { 84*f4a2713aSLionel Sambuc return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} 85*f4a2713aSLionel Sambuc } 86*f4a2713aSLionel Sambuc 87*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 88*f4a2713aSLionel Sambuc // unix-fns.c : dispatch_once 89*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 90*f4a2713aSLionel Sambuc typedef void (^dispatch_block_t)(void); 91*f4a2713aSLionel Sambuc typedef long dispatch_once_t; 92*f4a2713aSLionel Sambuc void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) __attribute__((weak_import)); 93*f4a2713aSLionel Sambuc 94*f4a2713aSLionel Sambuc void test_dispatch_once() { 95*f4a2713aSLionel Sambuc dispatch_once_t pred = 0; 96*f4a2713aSLionel Sambuc do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // expected-warning{{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}} 97*f4a2713aSLionel Sambuc } 98*f4a2713aSLionel Sambuc void test_dispatch_once_neg() { 99*f4a2713aSLionel Sambuc static dispatch_once_t pred = 0; 100*f4a2713aSLionel Sambuc do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // no-warning 101*f4a2713aSLionel Sambuc } 102*f4a2713aSLionel Sambuc 103*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 104*f4a2713aSLionel Sambuc // retain-release-path-notes.m 105*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------=== 106*f4a2713aSLionel Sambuc typedef struct CFType *CFTypeRef; 107*f4a2713aSLionel Sambuc CFTypeRef CFCreateSomething() __attribute__((weak_import)); 108*f4a2713aSLionel Sambuc CFTypeRef CFGetSomething() __attribute__((weak_import)); 109*f4a2713aSLionel Sambuc 110*f4a2713aSLionel Sambuc CFTypeRef CFCopyRuleViolation () { 111*f4a2713aSLionel Sambuc CFTypeRef object = CFGetSomething(); 112*f4a2713aSLionel Sambuc return object; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 113*f4a2713aSLionel Sambuc } 114*f4a2713aSLionel Sambuc 115*f4a2713aSLionel Sambuc CFTypeRef CFGetRuleViolation () { 116*f4a2713aSLionel Sambuc CFTypeRef object = CFCreateSomething(); // expected-warning{{Potential leak of an object stored into 'object'}} 117*f4a2713aSLionel Sambuc return object; } 118