xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/inline.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc void clang_analyzer_eval(int);
4*f4a2713aSLionel Sambuc void clang_analyzer_checkInlined(int);
5*f4a2713aSLionel Sambuc 
test1_f1()6*f4a2713aSLionel Sambuc int test1_f1() {
7*f4a2713aSLionel Sambuc   int y = 1;
8*f4a2713aSLionel Sambuc   y++;
9*f4a2713aSLionel Sambuc   clang_analyzer_checkInlined(1); // expected-warning{{TRUE}}
10*f4a2713aSLionel Sambuc   return y;
11*f4a2713aSLionel Sambuc }
12*f4a2713aSLionel Sambuc 
test1_f2()13*f4a2713aSLionel Sambuc void test1_f2() {
14*f4a2713aSLionel Sambuc   int x = 1;
15*f4a2713aSLionel Sambuc   x = test1_f1();
16*f4a2713aSLionel Sambuc   if (x == 1) {
17*f4a2713aSLionel Sambuc     int *p = 0;
18*f4a2713aSLionel Sambuc     *p = 3; // no-warning
19*f4a2713aSLionel Sambuc   }
20*f4a2713aSLionel Sambuc   if (x == 2) {
21*f4a2713aSLionel Sambuc     int *p = 0;
22*f4a2713aSLionel Sambuc     *p = 3; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
23*f4a2713aSLionel Sambuc   }
24*f4a2713aSLionel Sambuc }
25*f4a2713aSLionel Sambuc 
26*f4a2713aSLionel Sambuc // Test that inlining works when the declared function has less arguments
27*f4a2713aSLionel Sambuc // than the actual number in the declaration.
test2_f1()28*f4a2713aSLionel Sambuc void test2_f1() {}
29*f4a2713aSLionel Sambuc int test2_f2();
30*f4a2713aSLionel Sambuc 
test2_f3()31*f4a2713aSLionel Sambuc void test2_f3() {
32*f4a2713aSLionel Sambuc   test2_f1(test2_f2()); // expected-warning{{too many arguments in call to 'test2_f1'}}
33*f4a2713aSLionel Sambuc }
34*f4a2713aSLionel Sambuc 
35*f4a2713aSLionel Sambuc // Test that inlining works with recursive functions.
36*f4a2713aSLionel Sambuc 
factorial(unsigned x)37*f4a2713aSLionel Sambuc unsigned factorial(unsigned x) {
38*f4a2713aSLionel Sambuc   if (x <= 1)
39*f4a2713aSLionel Sambuc     return 1;
40*f4a2713aSLionel Sambuc   return x * factorial(x - 1);
41*f4a2713aSLionel Sambuc }
42*f4a2713aSLionel Sambuc 
test_factorial()43*f4a2713aSLionel Sambuc void test_factorial() {
44*f4a2713aSLionel Sambuc   if (factorial(3) == 6) {
45*f4a2713aSLionel Sambuc     int *p = 0;
46*f4a2713aSLionel Sambuc     *p = 0xDEADBEEF;  // expected-warning {{null}}
47*f4a2713aSLionel Sambuc   }
48*f4a2713aSLionel Sambuc   else {
49*f4a2713aSLionel Sambuc     int *p = 0;
50*f4a2713aSLionel Sambuc     *p = 0xDEADBEEF; // no-warning
51*f4a2713aSLionel Sambuc   }
52*f4a2713aSLionel Sambuc }
53*f4a2713aSLionel Sambuc 
test_factorial_2()54*f4a2713aSLionel Sambuc void test_factorial_2() {
55*f4a2713aSLionel Sambuc   unsigned x = factorial(3);
56*f4a2713aSLionel Sambuc   if (x == factorial(3)) {
57*f4a2713aSLionel Sambuc     int *p = 0;
58*f4a2713aSLionel Sambuc     *p = 0xDEADBEEF;  // expected-warning {{null}}
59*f4a2713aSLionel Sambuc   }
60*f4a2713aSLionel Sambuc   else {
61*f4a2713aSLionel Sambuc     int *p = 0;
62*f4a2713aSLionel Sambuc     *p = 0xDEADBEEF; // no-warning
63*f4a2713aSLionel Sambuc   }
64*f4a2713aSLionel Sambuc }
65*f4a2713aSLionel Sambuc 
66*f4a2713aSLionel Sambuc // Test that returning stack memory from a parent stack frame does
67*f4a2713aSLionel Sambuc // not trigger a warning.
return_buf(char * buf)68*f4a2713aSLionel Sambuc static char *return_buf(char *buf) {
69*f4a2713aSLionel Sambuc   return buf + 10;
70*f4a2713aSLionel Sambuc }
71*f4a2713aSLionel Sambuc 
test_return_stack_memory_ok()72*f4a2713aSLionel Sambuc void test_return_stack_memory_ok() {
73*f4a2713aSLionel Sambuc   char stack_buf[100];
74*f4a2713aSLionel Sambuc   char *pos = return_buf(stack_buf);
75*f4a2713aSLionel Sambuc   (void) pos;
76*f4a2713aSLionel Sambuc }
77*f4a2713aSLionel Sambuc 
test_return_stack_memory_bad()78*f4a2713aSLionel Sambuc char *test_return_stack_memory_bad() {
79*f4a2713aSLionel Sambuc   char stack_buf[100];
80*f4a2713aSLionel Sambuc   char *x = stack_buf;
81*f4a2713aSLionel Sambuc   return x; // expected-warning {{stack memory associated}}
82*f4a2713aSLionel Sambuc }
83*f4a2713aSLionel Sambuc 
84*f4a2713aSLionel Sambuc // Test that passing a struct value with an uninitialized field does
85*f4a2713aSLionel Sambuc // not trigger a warning if we are inlining and the body is available.
86*f4a2713aSLionel Sambuc struct rdar10977037 { int x, y; };
test_rdar10977037_aux(struct rdar10977037 v)87*f4a2713aSLionel Sambuc int test_rdar10977037_aux(struct rdar10977037 v) { return v.y; }
88*f4a2713aSLionel Sambuc int test_rdar10977037_aux_2(struct rdar10977037 v);
test_rdar10977037()89*f4a2713aSLionel Sambuc int test_rdar10977037() {
90*f4a2713aSLionel Sambuc   struct rdar10977037 v;
91*f4a2713aSLionel Sambuc   v.y = 1;
92*f4a2713aSLionel Sambuc   v. y += test_rdar10977037_aux(v); // no-warning
93*f4a2713aSLionel Sambuc   return test_rdar10977037_aux_2(v); // expected-warning {{Passed-by-value struct argument contains uninitialized data}}
94*f4a2713aSLionel Sambuc }
95*f4a2713aSLionel Sambuc 
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc // Test inlining a forward-declared function.
98*f4a2713aSLionel Sambuc // This regressed when CallEvent was first introduced.
99*f4a2713aSLionel Sambuc int plus1(int x);
test()100*f4a2713aSLionel Sambuc void test() {
101*f4a2713aSLionel Sambuc   clang_analyzer_eval(plus1(2) == 3); // expected-warning{{TRUE}}
102*f4a2713aSLionel Sambuc }
103*f4a2713aSLionel Sambuc 
plus1(int x)104*f4a2713aSLionel Sambuc int plus1(int x) {
105*f4a2713aSLionel Sambuc   return x + 1;
106*f4a2713aSLionel Sambuc }
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc 
never_called_by_anyone()109*f4a2713aSLionel Sambuc void never_called_by_anyone() {
110*f4a2713aSLionel Sambuc   clang_analyzer_checkInlined(0); // no-warning
111*f4a2713aSLionel Sambuc }
112*f4a2713aSLionel Sambuc 
113*f4a2713aSLionel Sambuc 
knr_one_argument(a)114*f4a2713aSLionel Sambuc void knr_one_argument(a) int a; { }
115*f4a2713aSLionel Sambuc 
call_with_less_arguments()116*f4a2713aSLionel Sambuc void call_with_less_arguments() {
117*f4a2713aSLionel Sambuc   knr_one_argument(); // expected-warning{{too few arguments}} expected-warning{{Function taking 1 argument}}
118*f4a2713aSLionel Sambuc }
119