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