// RUN: %clang_analyze_cc1 -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix.Stream \ // RUN: -analyzer-checker=debug.ExprInspection #include "Inputs/system-header-simulator.h" #include "Inputs/system-header-simulator-for-valist.h" void clang_analyzer_eval(int); void clang_analyzer_dump(int); void test_fread(void) { FILE *F = fopen("file", "r+"); if (!F) return; char Buf[3] = {10, 10, 10}; fread(Buf, 1, 3, F); // The check applies to success and failure. clang_analyzer_dump(Buf[0]); // expected-warning {{conj_$}} Should not preserve the previous value, thus should not be 10. clang_analyzer_dump(Buf[2]); // expected-warning {{conj_$}} if (feof(F)) { char Buf1[3] = {10, 10, 10}; fread(Buf1, 1, 3, F); // expected-warning {{is in EOF state}} clang_analyzer_dump(Buf1[0]); // expected-warning {{10 S32b}} clang_analyzer_dump(Buf1[2]); // expected-warning {{10 S32b}} } fclose(F); } void test_fwrite(void) { FILE *F = fopen("file", "r+"); if (!F) return; char Buf[3] = {10, 10, 10}; fwrite(Buf, 1, 3, F); // The check applies to success and failure. clang_analyzer_dump(Buf[0]); // expected-warning {{10 S32b}} clang_analyzer_dump(Buf[2]); // expected-warning {{10 S32b}} fclose(F); } void test_fgets() { FILE *F = tmpfile(); if (!F) return; char Buf[3] = {10, 10, 10}; fgets(Buf, 3, F); // The check applies to success and failure. clang_analyzer_dump(Buf[0]); // expected-warning {{conj_$}} Should not preserve the previous value, thus should not be 10. clang_analyzer_dump(Buf[2]); // expected-warning {{conj_$}} if (feof(F)) { char Buf1[3] = {10, 10, 10}; fgets(Buf1, 3, F); // expected-warning {{is in EOF state}} clang_analyzer_dump(Buf1[0]); // expected-warning {{10 S32b}} clang_analyzer_dump(Buf1[2]); // expected-warning {{10 S32b}} } fclose(F); } void test_fputs() { FILE *F = tmpfile(); if (!F) return; char *Buf = "aaa"; fputs(Buf, F); // The check applies to success and failure. clang_analyzer_dump(Buf[0]); // expected-warning {{97 S32b}} clang_analyzer_dump(Buf[2]); // expected-warning {{97 S32b}} clang_analyzer_dump(Buf[3]); // expected-warning {{0 S32b}} fclose(F); } void test_fscanf() { FILE *F = tmpfile(); if (!F) return; int a = 1; unsigned b; int Ret = fscanf(F, "%d %u", &a, &b); if (Ret == 0) { clang_analyzer_dump(a); // expected-warning {{conj_$}} // FIXME: should be {{1 S32b}}. clang_analyzer_dump(b); // expected-warning {{conj_$}} // FIXME: should be {{uninitialized value}}. } else if (Ret == 1) { clang_analyzer_dump(a); // expected-warning {{conj_$}} clang_analyzer_dump(b); // expected-warning {{conj_$}} // FIXME: should be {{uninitialized value}}. } else if (Ret >= 2) { clang_analyzer_dump(a); // expected-warning {{conj_$}} clang_analyzer_dump(b); // expected-warning {{conj_$}} clang_analyzer_eval(Ret == 2); // expected-warning {{FALSE}} expected-warning {{TRUE}} // FIXME: should be only TRUE. } else { clang_analyzer_dump(a); // expected-warning {{1 S32b}} clang_analyzer_dump(b); // expected-warning {{uninitialized value}} } fclose(F); } void test_getdelim(char *P, size_t Sz) { FILE *F = tmpfile(); if (!F) return; char *P1 = P; size_t Sz1 = Sz; ssize_t Ret = getdelim(&P, &Sz, '\t', F); if (Ret < 0) { clang_analyzer_eval(P == P1); // expected-warning {{FALSE}} \ // expected-warning {{TRUE}} clang_analyzer_eval(Sz == Sz1); // expected-warning {{FALSE}} \ // expected-warning {{TRUE}} } else { clang_analyzer_eval(P == P1); // expected-warning {{FALSE}} \ // expected-warning {{TRUE}} clang_analyzer_eval(Sz == Sz1); // expected-warning {{FALSE}} \ // expected-warning {{TRUE}} } fclose(F); } void test_fgetpos() { FILE *F = tmpfile(); if (!F) return; fpos_t Pos = 1; int Ret = fgetpos(F, &Pos); if (Ret == 0) { clang_analyzer_dump(Pos); // expected-warning {{conj_$}} } else { clang_analyzer_dump(Pos); // expected-warning {{1 S32b}} } fclose(F); } void test_fprintf() { FILE *F1 = tmpfile(); if (!F1) return; unsigned a = 42; char *output = "HELLO"; int r = fprintf(F1, "%s\t%u\n", output, a); // fprintf does not invalidate any of its input // 69 is ascii for 'E' clang_analyzer_dump(a); // expected-warning {{42 S32b}} clang_analyzer_dump(output[1]); // expected-warning {{69 S32b}} fclose(F1); } int test_vfscanf_inner(const char *fmt, ...) { FILE *F1 = tmpfile(); if (!F1) return EOF; va_list ap; va_start(ap, fmt); int r = vfscanf(F1, fmt, ap); fclose(F1); va_end(ap); return r; } void test_vfscanf() { int i = 42; int j = 43; int r = test_vfscanf_inner("%d", &i); if (r != EOF) { // i gets invalidated by the call to test_vfscanf_inner, not by vfscanf. clang_analyzer_dump(i); // expected-warning {{conj_$}} clang_analyzer_dump(j); // expected-warning {{43 S32b}} } }