15ca87759SBalázs Kéri // RUN: %clang_analyze_cc1 -verify %s \
25ca87759SBalázs Kéri // RUN: -analyzer-checker=core \
3*09f160c6SBalázs Kéri // RUN: -analyzer-checker=unix.Stream \
45ca87759SBalázs Kéri // RUN: -analyzer-checker=debug.ExprInspection
55ca87759SBalázs Kéri
65ca87759SBalázs Kéri #include "Inputs/system-header-simulator.h"
7239312e4SAlejandro Álvarez Ayllón #include "Inputs/system-header-simulator-for-valist.h"
85ca87759SBalázs Kéri
95ca87759SBalázs Kéri void clang_analyzer_eval(int);
105ca87759SBalázs Kéri void clang_analyzer_dump(int);
115ca87759SBalázs Kéri
test_fread(void)125ca87759SBalázs Kéri void test_fread(void) {
135ca87759SBalázs Kéri FILE *F = fopen("file", "r+");
145ca87759SBalázs Kéri if (!F)
155ca87759SBalázs Kéri return;
165ca87759SBalázs Kéri
175ca87759SBalázs Kéri char Buf[3] = {10, 10, 10};
185ca87759SBalázs Kéri fread(Buf, 1, 3, F);
195ca87759SBalázs Kéri // The check applies to success and failure.
205ca87759SBalázs Kéri clang_analyzer_dump(Buf[0]); // expected-warning {{conj_$}} Should not preserve the previous value, thus should not be 10.
215ca87759SBalázs Kéri clang_analyzer_dump(Buf[2]); // expected-warning {{conj_$}}
225ca87759SBalázs Kéri if (feof(F)) {
235ca87759SBalázs Kéri char Buf1[3] = {10, 10, 10};
245ca87759SBalázs Kéri fread(Buf1, 1, 3, F); // expected-warning {{is in EOF state}}
255ca87759SBalázs Kéri clang_analyzer_dump(Buf1[0]); // expected-warning {{10 S32b}}
265ca87759SBalázs Kéri clang_analyzer_dump(Buf1[2]); // expected-warning {{10 S32b}}
275ca87759SBalázs Kéri }
285ca87759SBalázs Kéri
295ca87759SBalázs Kéri fclose(F);
305ca87759SBalázs Kéri }
315ca87759SBalázs Kéri
test_fwrite(void)325ca87759SBalázs Kéri void test_fwrite(void) {
335ca87759SBalázs Kéri FILE *F = fopen("file", "r+");
345ca87759SBalázs Kéri if (!F)
355ca87759SBalázs Kéri return;
365ca87759SBalázs Kéri
375ca87759SBalázs Kéri char Buf[3] = {10, 10, 10};
385ca87759SBalázs Kéri fwrite(Buf, 1, 3, F);
395ca87759SBalázs Kéri // The check applies to success and failure.
405ca87759SBalázs Kéri clang_analyzer_dump(Buf[0]); // expected-warning {{10 S32b}}
415ca87759SBalázs Kéri clang_analyzer_dump(Buf[2]); // expected-warning {{10 S32b}}
425ca87759SBalázs Kéri
435ca87759SBalázs Kéri fclose(F);
445ca87759SBalázs Kéri }
455ca87759SBalázs Kéri
test_fgets()465ca87759SBalázs Kéri void test_fgets() {
475ca87759SBalázs Kéri FILE *F = tmpfile();
485ca87759SBalázs Kéri if (!F)
495ca87759SBalázs Kéri return;
505ca87759SBalázs Kéri
515ca87759SBalázs Kéri char Buf[3] = {10, 10, 10};
525ca87759SBalázs Kéri fgets(Buf, 3, F);
535ca87759SBalázs Kéri // The check applies to success and failure.
545ca87759SBalázs Kéri clang_analyzer_dump(Buf[0]); // expected-warning {{conj_$}} Should not preserve the previous value, thus should not be 10.
555ca87759SBalázs Kéri clang_analyzer_dump(Buf[2]); // expected-warning {{conj_$}}
565ca87759SBalázs Kéri if (feof(F)) {
575ca87759SBalázs Kéri char Buf1[3] = {10, 10, 10};
585ca87759SBalázs Kéri fgets(Buf1, 3, F); // expected-warning {{is in EOF state}}
595ca87759SBalázs Kéri clang_analyzer_dump(Buf1[0]); // expected-warning {{10 S32b}}
605ca87759SBalázs Kéri clang_analyzer_dump(Buf1[2]); // expected-warning {{10 S32b}}
615ca87759SBalázs Kéri }
625ca87759SBalázs Kéri
635ca87759SBalázs Kéri fclose(F);
645ca87759SBalázs Kéri }
655ca87759SBalázs Kéri
test_fputs()665ca87759SBalázs Kéri void test_fputs() {
675ca87759SBalázs Kéri FILE *F = tmpfile();
685ca87759SBalázs Kéri if (!F)
695ca87759SBalázs Kéri return;
705ca87759SBalázs Kéri
715ca87759SBalázs Kéri char *Buf = "aaa";
725ca87759SBalázs Kéri fputs(Buf, F);
735ca87759SBalázs Kéri // The check applies to success and failure.
745ca87759SBalázs Kéri clang_analyzer_dump(Buf[0]); // expected-warning {{97 S32b}}
755ca87759SBalázs Kéri clang_analyzer_dump(Buf[2]); // expected-warning {{97 S32b}}
765ca87759SBalázs Kéri clang_analyzer_dump(Buf[3]); // expected-warning {{0 S32b}}
775ca87759SBalázs Kéri
785ca87759SBalázs Kéri fclose(F);
795ca87759SBalázs Kéri }
805ca87759SBalázs Kéri
test_fscanf()815ca87759SBalázs Kéri void test_fscanf() {
825ca87759SBalázs Kéri FILE *F = tmpfile();
835ca87759SBalázs Kéri if (!F)
845ca87759SBalázs Kéri return;
855ca87759SBalázs Kéri
865ca87759SBalázs Kéri int a = 1;
875ca87759SBalázs Kéri unsigned b;
885ca87759SBalázs Kéri int Ret = fscanf(F, "%d %u", &a, &b);
895ca87759SBalázs Kéri if (Ret == 0) {
905ca87759SBalázs Kéri clang_analyzer_dump(a); // expected-warning {{conj_$}}
915ca87759SBalázs Kéri // FIXME: should be {{1 S32b}}.
925ca87759SBalázs Kéri clang_analyzer_dump(b); // expected-warning {{conj_$}}
935ca87759SBalázs Kéri // FIXME: should be {{uninitialized value}}.
945ca87759SBalázs Kéri } else if (Ret == 1) {
955ca87759SBalázs Kéri clang_analyzer_dump(a); // expected-warning {{conj_$}}
965ca87759SBalázs Kéri clang_analyzer_dump(b); // expected-warning {{conj_$}}
975ca87759SBalázs Kéri // FIXME: should be {{uninitialized value}}.
985ca87759SBalázs Kéri } else if (Ret >= 2) {
995ca87759SBalázs Kéri clang_analyzer_dump(a); // expected-warning {{conj_$}}
1005ca87759SBalázs Kéri clang_analyzer_dump(b); // expected-warning {{conj_$}}
1015ca87759SBalázs Kéri clang_analyzer_eval(Ret == 2); // expected-warning {{FALSE}} expected-warning {{TRUE}}
1025ca87759SBalázs Kéri // FIXME: should be only TRUE.
1035ca87759SBalázs Kéri } else {
1045ca87759SBalázs Kéri clang_analyzer_dump(a); // expected-warning {{1 S32b}}
1055ca87759SBalázs Kéri clang_analyzer_dump(b); // expected-warning {{uninitialized value}}
1065ca87759SBalázs Kéri }
1075ca87759SBalázs Kéri
1085ca87759SBalázs Kéri fclose(F);
1095ca87759SBalázs Kéri }
1105ca87759SBalázs Kéri
test_getdelim(char * P,size_t Sz)1115ca87759SBalázs Kéri void test_getdelim(char *P, size_t Sz) {
1125ca87759SBalázs Kéri FILE *F = tmpfile();
1135ca87759SBalázs Kéri if (!F)
1145ca87759SBalázs Kéri return;
1155ca87759SBalázs Kéri
1165ca87759SBalázs Kéri char *P1 = P;
1175ca87759SBalázs Kéri size_t Sz1 = Sz;
1185ca87759SBalázs Kéri ssize_t Ret = getdelim(&P, &Sz, '\t', F);
1195ca87759SBalázs Kéri if (Ret < 0) {
1205ca87759SBalázs Kéri clang_analyzer_eval(P == P1); // expected-warning {{FALSE}} \
1215ca87759SBalázs Kéri // expected-warning {{TRUE}}
1225ca87759SBalázs Kéri clang_analyzer_eval(Sz == Sz1); // expected-warning {{FALSE}} \
1235ca87759SBalázs Kéri // expected-warning {{TRUE}}
1245ca87759SBalázs Kéri } else {
1255ca87759SBalázs Kéri clang_analyzer_eval(P == P1); // expected-warning {{FALSE}} \
1265ca87759SBalázs Kéri // expected-warning {{TRUE}}
1275ca87759SBalázs Kéri clang_analyzer_eval(Sz == Sz1); // expected-warning {{FALSE}} \
1285ca87759SBalázs Kéri // expected-warning {{TRUE}}
1295ca87759SBalázs Kéri }
1305ca87759SBalázs Kéri
1315ca87759SBalázs Kéri fclose(F);
1325ca87759SBalázs Kéri }
1335ca87759SBalázs Kéri
test_fgetpos()1345ca87759SBalázs Kéri void test_fgetpos() {
1355ca87759SBalázs Kéri FILE *F = tmpfile();
1365ca87759SBalázs Kéri if (!F)
1375ca87759SBalázs Kéri return;
1385ca87759SBalázs Kéri
1395ca87759SBalázs Kéri fpos_t Pos = 1;
1405ca87759SBalázs Kéri int Ret = fgetpos(F, &Pos);
1415ca87759SBalázs Kéri if (Ret == 0) {
1425ca87759SBalázs Kéri clang_analyzer_dump(Pos); // expected-warning {{conj_$}}
1435ca87759SBalázs Kéri } else {
1445ca87759SBalázs Kéri clang_analyzer_dump(Pos); // expected-warning {{1 S32b}}
1455ca87759SBalázs Kéri }
1465ca87759SBalázs Kéri
1475ca87759SBalázs Kéri fclose(F);
1485ca87759SBalázs Kéri }
149239312e4SAlejandro Álvarez Ayllón
test_fprintf()150239312e4SAlejandro Álvarez Ayllón void test_fprintf() {
151239312e4SAlejandro Álvarez Ayllón FILE *F1 = tmpfile();
152239312e4SAlejandro Álvarez Ayllón if (!F1)
153239312e4SAlejandro Álvarez Ayllón return;
154239312e4SAlejandro Álvarez Ayllón
155239312e4SAlejandro Álvarez Ayllón unsigned a = 42;
156239312e4SAlejandro Álvarez Ayllón char *output = "HELLO";
157239312e4SAlejandro Álvarez Ayllón int r = fprintf(F1, "%s\t%u\n", output, a);
158239312e4SAlejandro Álvarez Ayllón // fprintf does not invalidate any of its input
159239312e4SAlejandro Álvarez Ayllón // 69 is ascii for 'E'
160239312e4SAlejandro Álvarez Ayllón clang_analyzer_dump(a); // expected-warning {{42 S32b}}
161239312e4SAlejandro Álvarez Ayllón clang_analyzer_dump(output[1]); // expected-warning {{69 S32b}}
162239312e4SAlejandro Álvarez Ayllón fclose(F1);
163239312e4SAlejandro Álvarez Ayllón }
164239312e4SAlejandro Álvarez Ayllón
test_vfscanf_inner(const char * fmt,...)165239312e4SAlejandro Álvarez Ayllón int test_vfscanf_inner(const char *fmt, ...) {
166239312e4SAlejandro Álvarez Ayllón FILE *F1 = tmpfile();
167239312e4SAlejandro Álvarez Ayllón if (!F1)
168239312e4SAlejandro Álvarez Ayllón return EOF;
169239312e4SAlejandro Álvarez Ayllón
170239312e4SAlejandro Álvarez Ayllón va_list ap;
171239312e4SAlejandro Álvarez Ayllón va_start(ap, fmt);
172239312e4SAlejandro Álvarez Ayllón
173239312e4SAlejandro Álvarez Ayllón int r = vfscanf(F1, fmt, ap);
174239312e4SAlejandro Álvarez Ayllón
175239312e4SAlejandro Álvarez Ayllón fclose(F1);
176239312e4SAlejandro Álvarez Ayllón va_end(ap);
177239312e4SAlejandro Álvarez Ayllón return r;
178239312e4SAlejandro Álvarez Ayllón }
179239312e4SAlejandro Álvarez Ayllón
test_vfscanf()180239312e4SAlejandro Álvarez Ayllón void test_vfscanf() {
181239312e4SAlejandro Álvarez Ayllón int i = 42;
182239312e4SAlejandro Álvarez Ayllón int j = 43;
183239312e4SAlejandro Álvarez Ayllón int r = test_vfscanf_inner("%d", &i);
184239312e4SAlejandro Álvarez Ayllón if (r != EOF) {
185239312e4SAlejandro Álvarez Ayllón // i gets invalidated by the call to test_vfscanf_inner, not by vfscanf.
186239312e4SAlejandro Álvarez Ayllón clang_analyzer_dump(i); // expected-warning {{conj_$}}
187239312e4SAlejandro Álvarez Ayllón clang_analyzer_dump(j); // expected-warning {{43 S32b}}
188239312e4SAlejandro Álvarez Ayllón }
189239312e4SAlejandro Álvarez Ayllón }
190