mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 22:36:34 +00:00
190 lines
5.0 KiB
C
190 lines
5.0 KiB
C
// 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}}
|
|
}
|
|
}
|