Files
clang-p2996/clang/test/Analysis/stream-note.c
Balázs Kéri 570bf972f5 [clang][analyzer] Remove report of null stream from StreamChecker.
The case of NULL stream passed to stream functions was reported by StreamChecker.
The same condition is checked already by StdLibraryFunctionsChecker and it is
enough to check at one place. The StreamChecker stops now analysis if a passed NULL
stream is encountered but generates no report.
This change removes a dependency between StdCLibraryFunctionArgs checker and
StreamChecker. There is now no more specific message reported by StreamChecker,
the previous weak-dependency is not needed. And StreamChecker can be used
without StdCLibraryFunctions checker or its ModelPOSIX option.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D137790
2023-01-09 09:49:08 +01:00

152 lines
5.7 KiB
C

// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text \
// RUN: -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,alpha.unix.StdCLibraryFunctionArgs -analyzer-output text \
// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true -verify=expected,stdargs %s
#include "Inputs/system-header-simulator.h"
void check_note_at_correct_open(void) {
FILE *F1 = tmpfile(); // expected-note {{Stream opened here}}
if (!F1)
// expected-note@-1 {{'F1' is non-null}}
// expected-note@-2 {{Taking false branch}}
return;
FILE *F2 = tmpfile();
if (!F2) {
// expected-note@-1 {{'F2' is non-null}}
// expected-note@-2 {{Taking false branch}}
fclose(F1);
return;
}
rewind(F2);
fclose(F2);
rewind(F1);
}
// expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
// expected-note@-2 {{Opened stream never closed. Potential resource leak}}
void check_note_fopen(void) {
FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
if (!F)
// expected-note@-1 {{'F' is non-null}}
// expected-note@-2 {{Taking false branch}}
return;
}
// expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
// expected-note@-2 {{Opened stream never closed. Potential resource leak}}
void check_note_freopen(void) {
FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
if (!F)
// expected-note@-1 {{'F' is non-null}}
// expected-note@-2 {{Taking false branch}}
return;
F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
if (!F)
// expected-note@-1 {{'F' is non-null}}
// expected-note@-2 {{Taking false branch}}
return;
}
// expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
// expected-note@-2 {{Opened stream never closed. Potential resource leak}}
void check_note_leak_2(int c) {
FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
if (!F1)
// expected-note@-1 {{'F1' is non-null}}
// expected-note@-2 {{Taking false branch}}
// expected-note@-3 {{'F1' is non-null}}
// expected-note@-4 {{Taking false branch}}
return;
FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
if (!F2) {
// expected-note@-1 {{'F2' is non-null}}
// expected-note@-2 {{Taking false branch}}
// expected-note@-3 {{'F2' is non-null}}
// expected-note@-4 {{Taking false branch}}
fclose(F1);
return;
}
if (c)
// expected-note@-1 {{Assuming 'c' is not equal to 0}}
// expected-note@-2 {{Taking true branch}}
// expected-note@-3 {{Assuming 'c' is not equal to 0}}
// expected-note@-4 {{Taking true branch}}
return;
// expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
// expected-note@-2 {{Opened stream never closed. Potential resource leak}}
// expected-warning@-3 {{Opened stream never closed. Potential resource leak}}
// expected-note@-4 {{Opened stream never closed. Potential resource leak}}
fclose(F1);
fclose(F2);
}
void check_track_null(void) {
FILE *F;
F = fopen("foo1.c", "r"); // stdargs-note {{Value assigned to 'F'}} stdargs-note {{Assuming pointer value is null}}
if (F != NULL) { // stdargs-note {{Taking false branch}} stdargs-note {{'F' is equal to NULL}}
fclose(F);
return;
}
fclose(F); // stdargs-warning {{Function argument constraint is not satisfied}}
// stdargs-note@-1 {{Function argument constraint is not satisfied}}
// stdargs-note@-2 {{The 1st argument should not be NULL}}
}
void check_eof_notes_feof_after_feof(void) {
FILE *F;
char Buf[10];
F = fopen("foo1.c", "r");
if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
return;
}
fread(Buf, 1, 1, F);
if (feof(F)) { // expected-note {{Taking true branch}}
clearerr(F);
fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
if (feof(F)) { // expected-note {{Taking true branch}}
fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
// expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
}
}
fclose(F);
}
void check_eof_notes_feof_after_no_feof(void) {
FILE *F;
char Buf[10];
F = fopen("foo1.c", "r");
if (F == NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
return;
}
fread(Buf, 1, 1, F);
if (feof(F)) { // expected-note {{Taking false branch}}
fclose(F);
return;
} else if (ferror(F)) { // expected-note {{Taking false branch}}
fclose(F);
return;
}
fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
if (feof(F)) { // expected-note {{Taking true branch}}
fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
// expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
}
fclose(F);
}
void check_eof_notes_feof_or_no_error(void) {
FILE *F;
char Buf[10];
F = fopen("foo1.c", "r");
if (F == NULL) // expected-note {{Taking false branch}} expected-note {{'F' is not equal to NULL}}
return;
int RRet = fread(Buf, 1, 1, F); // expected-note {{Assuming stream reaches end-of-file here}}
if (ferror(F)) { // expected-note {{Taking false branch}}
} else {
fread(Buf, 1, 1, F); // expected-warning {{Read function called when stream is in EOF state. Function has no effect}}
// expected-note@-1 {{Read function called when stream is in EOF state. Function has no effect}}
}
fclose(F);
}