1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s
3 #include "Inputs/system-header-simulator.h"
4 #include "Inputs/system-header-simulator-for-malloc.h"
5 #include "Inputs/system-header-simulator-for-valist.h"
7 void clang_analyzer_eval(int);
8 void clang_analyzer_dump_int(int);
9 void clang_analyzer_dump_ptr(void*);
10 void clang_analyzer_warnIfReached();
12 void test_getline_null_lineptr() {
19 getline(buffer
, &n
, F1
); // expected-warning {{Line pointer might be NULL}}
23 void test_getline_null_size() {
28 getline(&buffer
, NULL
, F1
); // expected-warning {{Size pointer might be NULL}}
32 void test_getline_null_buffer_size_gt0() {
38 getline(&buffer
, &n
, F1
); // ok since posix 2018
43 void test_getline_null_buffer_size_gt0_2(size_t n
) {
49 getline(&buffer
, &n
, F1
); // ok since posix 2018
55 void test_getline_null_buffer_unknown_size(size_t n
) {
61 getline(&buffer
, &n
, F1
); // ok
66 void test_getline_null_buffer_undef_size() {
74 getline(&buffer
, &n
, F1
); // ok since posix 2018
79 void test_getline_buffer_size_0() {
84 char *buffer
= malloc(10);
87 getline(&buffer
, &n
, F1
); // ok, the buffer is enough for 0 character
92 void test_getline_buffer_bad_size() {
97 char *buffer
= malloc(10);
100 getline(&buffer
, &n
, F1
); // expected-warning {{The buffer from the first argument is smaller than the size specified by the second parameter}}
105 void test_getline_buffer_smaller_size() {
106 FILE *F1
= tmpfile();
110 char *buffer
= malloc(100);
113 getline(&buffer
, &n
, F1
); // ok, there is enough space for 10 characters
118 void test_getline_buffer_undef_size() {
119 FILE *F1
= tmpfile();
123 char *buffer
= malloc(100);
126 getline(&buffer
, &n
, F1
); // expected-warning {{The buffer from the first argument is not NULL, but the size specified by the second parameter is undefined}}
132 void test_getline_null_buffer() {
133 FILE *F1
= tmpfile();
138 ssize_t r
= getline(&buffer
, &n
, F1
);
139 // getline returns -1 on failure, number of char reads on success (>= 0)
141 clang_analyzer_warnIfReached(); // must not happen
143 // The buffer could be allocated both on failure and success
144 clang_analyzer_dump_int(n
); // expected-warning {{conj_$}}
145 clang_analyzer_dump_ptr(buffer
); // expected-warning {{conj_$}}
151 void test_getdelim_null_size() {
152 FILE *F1
= tmpfile();
156 getdelim(&buffer
, NULL
, ',', F1
); // expected-warning {{Size pointer might be NULL}}
160 void test_getdelim_null_buffer_size_gt0() {
161 FILE *F1
= tmpfile();
166 getdelim(&buffer
, &n
, ';', F1
); // ok since posix 2018
171 void test_getdelim_null_buffer_size_gt0_2(size_t n
) {
172 FILE *F1
= tmpfile();
177 getdelim(&buffer
, &n
, ' ', F1
); // ok since posix 2018
183 void test_getdelim_null_buffer_unknown_size(size_t n
) {
184 FILE *F1
= tmpfile();
188 getdelim(&buffer
, &n
, '-', F1
); // ok
193 void test_getdelim_null_buffer() {
194 FILE *F1
= tmpfile();
199 ssize_t r
= getdelim(&buffer
, &n
, '\r', F1
);
200 // getdelim returns -1 on failure, number of char reads on success (>= 0)
202 clang_analyzer_warnIfReached(); // must not happen
205 // The buffer could be allocated both on failure and success
206 clang_analyzer_dump_int(n
); // expected-warning {{conj_$}}
207 clang_analyzer_dump_ptr(buffer
); // expected-warning {{conj_$}}
213 void test_getline_while() {
214 FILE *file
= fopen("file.txt", "r");
223 while ((read
= getline(&line
, &len
, file
)) != -1) {
224 printf("%s\n", line
);
231 void test_getline_return_check() {
232 FILE *file
= fopen("file.txt", "r");
239 ssize_t r
= getline(&line
, &len
, file
);
242 if (line
[0] == '\0') {} // ok
248 void test_getline_clear_eof() {
249 FILE *file
= fopen("file.txt", "r");
255 char *buffer
= malloc(n
);
256 ssize_t read
= fread(buffer
, n
, 1, file
);
259 getline(&buffer
, &n
, file
); // ok
265 void test_getline_not_null(char **buffer
, size_t *size
) {
266 FILE *file
= fopen("file.txt", "r");
271 getline(buffer
, size
, file
);
274 if (size
== NULL
|| buffer
== NULL
) {
275 clang_analyzer_warnIfReached(); // must not happen
279 void test_getline_size_constraint(size_t size
) {
280 FILE *file
= fopen("file.txt", "r");
285 size_t old_size
= size
;
286 char *buffer
= malloc(10);
287 if (buffer
!= NULL
) {
288 ssize_t r
= getline(&buffer
, &size
, file
);
290 // Since buffer has a size of 10, old_size must be less than or equal to 10.
291 // Otherwise, there would be UB.
292 clang_analyzer_eval(old_size
<= 10); // expected-warning{{TRUE}}
299 void test_getline_negative_buffer() {
300 FILE *file
= fopen("file.txt", "r");
307 getline(&buffer
, &n
, file
); // ok since posix 2018
312 void test_getline_negative_buffer_2(char *buffer
) {
313 FILE *file
= fopen("file.txt", "r");
319 (void)getline(&buffer
, &n
, file
); // ok