blob: 73d629a04ad22fc49c80f02a987e16b3ec22a51f [file] [log] [blame]
Jordan Roseee158bc2012-07-09 16:54:49 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
2
3void clang_analyzer_eval(int);
Zhongxing Xu1c625f22010-05-06 03:38:27 +00004
Ted Kremenekd4f482a2011-01-14 20:29:43 +00005int test1_f1() {
Zhongxing Xu06079d12010-02-27 02:44:37 +00006 int y = 1;
7 y++;
8 return y;
9}
10
Ted Kremenekd4f482a2011-01-14 20:29:43 +000011void test1_f2() {
Zhongxing Xu06079d12010-02-27 02:44:37 +000012 int x = 1;
Ted Kremenekd4f482a2011-01-14 20:29:43 +000013 x = test1_f1();
Zhongxing Xu06079d12010-02-27 02:44:37 +000014 if (x == 1) {
15 int *p = 0;
16 *p = 3; // no-warning
17 }
18 if (x == 2) {
19 int *p = 0;
Ted Kremenek452b84d2010-03-23 01:11:38 +000020 *p = 3; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
Zhongxing Xu06079d12010-02-27 02:44:37 +000021 }
22}
Ted Kremenekd4f482a2011-01-14 20:29:43 +000023
24// Test that inlining works when the declared function has less arguments
25// than the actual number in the declaration.
26void test2_f1() {}
27int test2_f2();
28
29void test2_f3() {
30 test2_f1(test2_f2()); // expected-warning{{too many arguments in call to 'test2_f1'}}
31}
32
Ted Kremenek0849ade2012-01-12 19:25:46 +000033// Test that inlining works with recursive functions.
34
35unsigned factorial(unsigned x) {
36 if (x <= 1)
37 return 1;
38 return x * factorial(x - 1);
39}
40
41void test_factorial() {
42 if (factorial(3) == 6) {
43 int *p = 0;
44 *p = 0xDEADBEEF; // expected-warning {{null}}
45 }
46 else {
47 int *p = 0;
48 *p = 0xDEADBEEF; // no-warning
49 }
50}
51
52void test_factorial_2() {
53 unsigned x = factorial(3);
54 if (x == factorial(3)) {
55 int *p = 0;
56 *p = 0xDEADBEEF; // expected-warning {{null}}
57 }
58 else {
59 int *p = 0;
60 *p = 0xDEADBEEF; // no-warning
61 }
62}
Ted Kremenek7e867832012-03-03 01:22:03 +000063
64// Test that returning stack memory from a parent stack frame does
65// not trigger a warning.
66static char *return_buf(char *buf) {
67 return buf + 10;
68}
69
70void test_return_stack_memory_ok() {
71 char stack_buf[100];
72 char *pos = return_buf(stack_buf);
73 (void) pos;
74}
75
76char *test_return_stack_memory_bad() {
77 char stack_buf[100];
78 char *x = stack_buf;
79 return x; // expected-warning {{stack memory associated}}
80}
81
Ted Kremeneke4d653b2012-03-05 23:57:14 +000082// Test that passing a struct value with an uninitialized field does
83// not trigger a warning if we are inlining and the body is available.
84struct rdar10977037 { int x, y; };
85int test_rdar10977037_aux(struct rdar10977037 v) { return v.y; }
86int test_rdar10977037_aux_2(struct rdar10977037 v);
87int test_rdar10977037() {
88 struct rdar10977037 v;
89 v.y = 1;
90 v. y += test_rdar10977037_aux(v); // no-warning
91 return test_rdar10977037_aux_2(v); // expected-warning {{Passed-by-value struct argument contains uninitialized data}}
92}
93
94
Jordan Roseee158bc2012-07-09 16:54:49 +000095// Test inlining a forward-declared function.
96// This regressed when CallEvent was first introduced.
97int plus1(int x);
98void test() {
99 clang_analyzer_eval(plus1(2) == 3); // expected-warning{{TRUE}}
100}
101
102int plus1(int x) {
103 return x + 1;
104}
105