1 // RUN: %clang_analyze_cc1 -verify %s -analyzer-output=text \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=unix.Stream
6 #include "Inputs/system-header-simulator.h"
10 [[noreturn
]] void halt();
17 //===----------------------------------------------------------------------===//
18 // Report for which we expect NoOwnershipChangeVisitor to add a new note.
19 //===----------------------------------------------------------------------===//
21 namespace stream_opened_in_fn_call
{
22 // TODO: AST analysis of sink would reveal that it doesn't intent to free the
23 // allocated memory, but in this instance, its also the only function with
24 // the ability to do so, we should see a note here.
29 sink(fopen("input.txt", "w"));
30 // expected-note@-1{{Stream opened here}}
31 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
32 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
33 } // namespace stream_opened_in_fn_call
35 namespace stream_passed_to_fn_call
{
37 void expectedClose(FILE *f
) {
38 if (char *log
= logDump()) { // expected-note{{Assuming 'log' is null}}
39 // expected-note@-1{{Taking false branch}}
43 } // expected-note{{Returning without closing stream object or storing it for later release}}
46 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
47 if (!f
) // expected-note{{'f' is non-null}}
48 // expected-note@-1{{Taking false branch}}
50 if (coin()) { // expected-note{{Assuming the condition is true}}
51 // expected-note@-1{{Taking true branch}}
52 expectedClose(f
); // expected-note{{Calling 'expectedClose'}}
53 // expected-note@-1{{Returning from 'expectedClose'}}
55 return; // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
56 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
60 } // namespace stream_passed_to_fn_call
62 namespace stream_shared_with_ptr_of_shorter_lifetime
{
66 if (coin()) // expected-note {{Assuming the condition is false}}
67 // expected-note@-1 {{Taking false branch}}
70 } // expected-note{{Returning without closing stream object or storing it for later release}}
73 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
74 if (!f
) // expected-note{{'f' is non-null}}
75 // expected-note@-1{{Taking false branch}}
77 sink(f
); // expected-note {{Calling 'sink'}}
78 // expected-note@-1 {{Returning from 'sink'}}
79 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
80 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
82 } // namespace stream_shared_with_ptr_of_shorter_lifetime
84 //===----------------------------------------------------------------------===//
85 // Report for which we *do not* expect NoOwnershipChangeVisitor add a new note,
86 // nor do we want it to.
87 //===----------------------------------------------------------------------===//
89 namespace stream_not_passed_to_fn_call
{
91 void expectedClose(FILE *f
) {
92 if (char *log
= logDump()) {
99 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
100 if (!f
) // expected-note{{'f' is non-null}}
101 // expected-note@-1{{Taking false branch}}
103 expectedClose(p
); // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
104 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
106 } // namespace stream_not_passed_to_fn_call
108 namespace stream_shared_with_ptr_of_same_lifetime
{
110 void expectedClose(FILE *f
, FILE **p
) {
111 // NOTE: Not a job of NoOwnershipChangeVisitor, but maybe this could be
112 // highlighted still?
117 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
119 if (!f
) // expected-note{{'f' is non-null}}
120 // expected-note@-1{{Taking false branch}}
122 expectedClose(f
, &p
);
123 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
124 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
125 } // namespace stream_shared_with_ptr_of_same_lifetime
127 namespace stream_passed_into_fn_that_doesnt_intend_to_free
{
128 void expectedClose(FILE *f
) {
132 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
133 if (!f
) // expected-note{{'f' is non-null}}
134 // expected-note@-1{{Taking false branch}}
138 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
139 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
140 } // namespace stream_passed_into_fn_that_doesnt_intend_to_free
142 namespace stream_passed_into_fn_that_doesnt_intend_to_free2
{
145 void expectedClose(FILE *f
) {
146 // Correctly realize that calling bar() doesn't mean that this function would
147 // like to deallocate anything.
152 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
153 if (!f
) // expected-note{{'f' is non-null}}
154 // expected-note@-1{{Taking false branch}}
158 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
159 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
160 } // namespace stream_passed_into_fn_that_doesnt_intend_to_free2
162 namespace streamstate_from_closed_to_open
{
164 // StreamState of the symbol changed from nothing to Allocated. We don't want to
165 // emit notes when the RefKind changes in the stack frame.
166 static FILE *fopenWrapper() {
167 FILE *f
= fopen("input.txt", "w"); // expected-note{{Stream opened here}}
173 v
= fopenWrapper(); // expected-note {{Calling 'fopenWrapper'}}
174 // expected-note@-1{{Returning from 'fopenWrapper'}}
176 } // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}
177 // expected-note@-1{{Opened stream never closed. Potential resource leak}}
179 } // namespace streamstate_from_closed_to_open