1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.unix.SimpleStream -verify %s
2
3#include "Inputs/system-header-simulator-for-simple-stream.h"
4
5void checkDoubleFClose(int *Data) {
6  FILE *F = fopen("myfile.txt", "w");
7  if (F != 0) {
8    fputs ("fopen example", F);
9    if (!Data)
10      fclose(F);
11    else
12      fputc(*Data, F);
13    fclose(F); // expected-warning {{Closing a previously closed file stream}}
14  }
15}
16
17int checkLeak(int *Data) {
18  FILE *F = fopen("myfile.txt", "w");
19  if (F != 0) {
20    fputs ("fopen example", F);
21  }
22
23  if (Data) // expected-warning {{Opened file is never closed; potential resource leak}}
24    return *Data;
25  else
26    return 0;
27}
28
29void checkLeakFollowedByAssert(int *Data) {
30  FILE *F = fopen("myfile.txt", "w");
31  if (F != 0) {
32    fputs ("fopen example", F);
33    if (!Data)
34      exit(0);
35    fclose(F);
36  }
37}
38
39void CloseOnlyOnValidFileHandle() {
40  FILE *F = fopen("myfile.txt", "w");
41  if (F)
42    fclose(F);
43  int x = 0; // no warning
44}
45
46void leakOnEnfOfPath1(int *Data) {
47  FILE *F = fopen("myfile.txt", "w");
48} // expected-warning {{Opened file is never closed; potential resource leak}}
49
50void leakOnEnfOfPath2(int *Data) {
51  FILE *F = fopen("myfile.txt", "w");
52  return; // expected-warning {{Opened file is never closed; potential resource leak}}
53}
54
55FILE *leakOnEnfOfPath3(int *Data) {
56  FILE *F = fopen("myfile.txt", "w");
57  return F;
58}
59
60void myfclose(FILE *F);
61void SymbolEscapedThroughFunctionCall() {
62  FILE *F = fopen("myfile.txt", "w");
63  myfclose(F);
64  return; // no warning
65}
66
67FILE *GlobalF;
68void SymbolEscapedThroughAssignmentToGloabl() {
69  FILE *F = fopen("myfile.txt", "w");
70  GlobalF = F;
71  return; // no warning
72}
73
74void SymbolDoesNotEscapeThoughStringAPIs(char *Data) {
75  FILE *F = fopen("myfile.txt", "w");
76  fputc(*Data, F);
77  return; // expected-warning {{Opened file is never closed; potential resource leak}}
78}
79
80void passConstPointer(const FILE * F);
81void testPassConstPointer() {
82  FILE *F = fopen("myfile.txt", "w");
83  passConstPointer(F);
84  return; // expected-warning {{Opened file is never closed; potential resource leak}}
85}
86
87void testPassToSystemHeaderFunctionIndirectly() {
88  FileStruct fs;
89  fs.p = fopen("myfile.txt", "w");
90  fakeSystemHeaderCall(&fs); // invalidates fs, making fs.p unreachable
91}  // no-warning
92