xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/weak-functions.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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