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