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 test1_f1()6int test1_f1() { 7 int y = 1; 8 y++; 9 clang_analyzer_checkInlined(1); // expected-warning{{TRUE}} 10 return y; 11 } 12 test1_f2()13void 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. test2_f1()28void test2_f1() {} 29 int test2_f2(); 30 test2_f3()31void 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 factorial(unsigned x)37unsigned factorial(unsigned x) { 38 if (x <= 1) 39 return 1; 40 return x * factorial(x - 1); 41 } 42 test_factorial()43void 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 test_factorial_2()54void 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. return_buf(char * buf)68static char *return_buf(char *buf) { 69 return buf + 10; 70 } 71 test_return_stack_memory_ok()72void test_return_stack_memory_ok() { 73 char stack_buf[100]; 74 char *pos = return_buf(stack_buf); 75 (void) pos; 76 } 77 test_return_stack_memory_bad()78char *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; }; test_rdar10977037_aux(struct rdar10977037 v)87int test_rdar10977037_aux(struct rdar10977037 v) { return v.y; } 88 int test_rdar10977037_aux_2(struct rdar10977037 v); test_rdar10977037()89int 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); test()100void test() { 101 clang_analyzer_eval(plus1(2) == 3); // expected-warning{{TRUE}} 102 } 103 plus1(int x)104int plus1(int x) { 105 return x + 1; 106 } 107 108 never_called_by_anyone()109void never_called_by_anyone() { 110 clang_analyzer_checkInlined(0); // no-warning 111 } 112 113 knr_one_argument(a)114void knr_one_argument(a) int a; { } 115 call_with_less_arguments()116void call_with_less_arguments() { 117 knr_one_argument(); // expected-warning{{too few arguments}} expected-warning{{Function taking 1 argument}} 118 } 119