xref: /llvm-project/clang/test/Analysis/stream-invalidate.c (revision 09f160c6298255f520b379b88161fbd1c365b308)
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