1 // Check the basic reporting/warning and the application of constraints. 2 // RUN: %clang_analyze_cc1 %s \ 3 // RUN: -analyzer-checker=core \ 4 // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ 5 // RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ 6 // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ 7 // RUN: -analyzer-checker=debug.ExprInspection \ 8 // RUN: -triple x86_64-unknown-linux-gnu \ 9 // RUN: -verify=report 10 11 // Check the bugpath related to the reports. 12 // RUN: %clang_analyze_cc1 %s \ 13 // RUN: -analyzer-checker=core \ 14 // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ 15 // RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ 16 // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ 17 // RUN: -analyzer-checker=debug.ExprInspection \ 18 // RUN: -triple x86_64-unknown-linux-gnu \ 19 // RUN: -analyzer-output=text \ 20 // RUN: -verify=bugpath 21 22 void clang_analyzer_eval(int); 23 24 int glob; 25 26 #define EOF -1 27 28 int isalnum(int); 29 30 void test_alnum_concrete(int v) { 31 int ret = isalnum(256); // \ 32 // report-warning{{Function argument constraint is not satisfied}} \ 33 // bugpath-warning{{Function argument constraint is not satisfied}} \ 34 // bugpath-note{{Function argument constraint is not satisfied}} 35 (void)ret; 36 } 37 38 void test_alnum_symbolic(int x) { 39 int ret = isalnum(x); 40 (void)ret; 41 42 clang_analyzer_eval(EOF <= x && x <= 255); // \ 43 // report-warning{{TRUE}} \ 44 // bugpath-warning{{TRUE}} \ 45 // bugpath-note{{TRUE}} \ 46 // bugpath-note{{Left side of '&&' is true}} \ 47 // bugpath-note{{'x' is <= 255}} 48 49 } 50 51 void test_alnum_symbolic2(int x) { 52 if (x > 255) { // \ 53 // bugpath-note{{Assuming 'x' is > 255}} \ 54 // bugpath-note{{Taking true branch}} 55 56 int ret = isalnum(x); // \ 57 // report-warning{{Function argument constraint is not satisfied}} \ 58 // bugpath-warning{{Function argument constraint is not satisfied}} \ 59 // bugpath-note{{Function argument constraint is not satisfied}} 60 61 (void)ret; 62 } 63 } 64 65 typedef struct FILE FILE; 66 typedef typeof(sizeof(int)) size_t; 67 size_t fread(void *restrict, size_t, size_t, FILE *); 68 void test_notnull_concrete(FILE *fp) { 69 fread(0, sizeof(int), 10, fp); // \ 70 // report-warning{{Function argument constraint is not satisfied}} \ 71 // bugpath-warning{{Function argument constraint is not satisfied}} \ 72 // bugpath-note{{Function argument constraint is not satisfied}} 73 } 74 void test_notnull_symbolic(FILE *fp, int *buf) { 75 fread(buf, sizeof(int), 10, fp); 76 clang_analyzer_eval(buf != 0); // \ 77 // report-warning{{TRUE}} \ 78 // bugpath-warning{{TRUE}} \ 79 // bugpath-note{{TRUE}} \ 80 // bugpath-note{{'buf' is not equal to null}} 81 } 82 void test_notnull_symbolic2(FILE *fp, int *buf) { 83 if (!buf) // bugpath-note{{Assuming 'buf' is null}} \ 84 // bugpath-note{{Taking true branch}} 85 fread(buf, sizeof(int), 10, fp); // \ 86 // report-warning{{Function argument constraint is not satisfied}} \ 87 // bugpath-warning{{Function argument constraint is not satisfied}} \ 88 // bugpath-note{{Function argument constraint is not satisfied}} 89 } 90 91 int __two_constrained_args(int, int); 92 void test_constraints_on_multiple_args(int x, int y) { 93 // State split should not happen here. I.e. x == 1 should not be evaluated 94 // FALSE. 95 __two_constrained_args(x, y); 96 clang_analyzer_eval(x == 1); // \ 97 // report-warning{{TRUE}} \ 98 // bugpath-warning{{TRUE}} \ 99 // bugpath-note{{TRUE}} 100 clang_analyzer_eval(y == 1); // \ 101 // report-warning{{TRUE}} \ 102 // bugpath-warning{{TRUE}} \ 103 // bugpath-note{{TRUE}} 104 } 105 106 int __arg_constrained_twice(int); 107 void test_multiple_constraints_on_same_arg(int x) { 108 __arg_constrained_twice(x); 109 // Check that both constraints are applied and only one branch is there. 110 clang_analyzer_eval(x < 1 || x > 2); // \ 111 // report-warning{{TRUE}} \ 112 // bugpath-warning{{TRUE}} \ 113 // bugpath-note{{TRUE}} \ 114 // bugpath-note{{Assuming 'x' is < 1}} \ 115 // bugpath-note{{Left side of '||' is true}} 116 } 117 118 int __variadic(void *stream, const char *format, ...); 119 void test_arg_constraint_on_variadic_fun() { 120 __variadic(0, "%d%d", 1, 2); // \ 121 // report-warning{{Function argument constraint is not satisfied}} \ 122 // bugpath-warning{{Function argument constraint is not satisfied}} \ 123 // bugpath-note{{Function argument constraint is not satisfied}} 124 } 125 126 int __buf_size_arg_constraint(const void *, size_t); 127 void test_buf_size_concrete() { 128 char buf[3]; // bugpath-note{{'buf' initialized here}} 129 __buf_size_arg_constraint(buf, 4); // \ 130 // report-warning{{Function argument constraint is not satisfied}} \ 131 // bugpath-warning{{Function argument constraint is not satisfied}} \ 132 // bugpath-note{{Function argument constraint is not satisfied}} 133 } 134 void test_buf_size_symbolic(int s) { 135 char buf[3]; 136 __buf_size_arg_constraint(buf, s); 137 clang_analyzer_eval(s <= 3); // \ 138 // report-warning{{TRUE}} \ 139 // bugpath-warning{{TRUE}} \ 140 // bugpath-note{{TRUE}} \ 141 // bugpath-note{{'s' is <= 3}} 142 } 143 void test_buf_size_symbolic_and_offset(int s) { 144 char buf[3]; 145 __buf_size_arg_constraint(buf + 1, s); 146 clang_analyzer_eval(s <= 2); // \ 147 // report-warning{{TRUE}} \ 148 // bugpath-warning{{TRUE}} \ 149 // bugpath-note{{TRUE}} \ 150 // bugpath-note{{'s' is <= 2}} 151 } 152