180 lines · cpp
1// RUN: %clang_analyze_cc1 -verify %s -analyzer-output=text \2// RUN: -analyzer-checker=core \3// RUN: -analyzer-checker=unix.Stream4 5 6#include "Inputs/system-header-simulator.h"7char *logDump();8bool coin();9 10[[noreturn]] void halt();11 12void assert(bool b) {13 if (!b)14 halt();15}16 17//===----------------------------------------------------------------------===//18// Report for which we expect NoOwnershipChangeVisitor to add a new note.19//===----------------------------------------------------------------------===//20 21namespace stream_opened_in_fn_call {22// TODO: AST analysis of sink would reveal that it doesn't intent to free the23// allocated memory, but in this instance, its also the only function with24// the ability to do so, we should see a note here.25void sink(FILE *f) {26}27 28void f() {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_call34 35namespace stream_passed_to_fn_call {36 37void expectedClose(FILE *f) {38 if (char *log = logDump()) { // expected-note{{Assuming 'log' is null}}39 // expected-note@-1{{Taking false branch}}40 printf("%s", log);41 fclose(f);42 }43} // expected-note{{Returning without closing stream object or storing it for later release}}44 45void f() {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}}49 return;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'}}54 55 return; // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}56 // expected-note@-1{{Opened stream never closed. Potential resource leak}}57 }58 fclose(f);59}60} // namespace stream_passed_to_fn_call61 62namespace stream_shared_with_ptr_of_shorter_lifetime {63 64void sink(FILE *f) {65 FILE *Q = f;66 if (coin()) // expected-note {{Assuming the condition is false}}67 // expected-note@-1 {{Taking false branch}}68 fclose(f);69 (void)Q;70} // expected-note{{Returning without closing stream object or storing it for later release}}71 72void foo() {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}}76 return;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}}81 82} // namespace stream_shared_with_ptr_of_shorter_lifetime83 84//===----------------------------------------------------------------------===//85// Report for which we *do not* expect NoOwnershipChangeVisitor add a new note,86// nor do we want it to.87//===----------------------------------------------------------------------===//88 89namespace stream_not_passed_to_fn_call {90 91void expectedClose(FILE *f) {92 if (char *log = logDump()) {93 printf("%s", log);94 fclose(f);95 }96}97 98void f(FILE *p) {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}}102 return;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}}105}106} // namespace stream_not_passed_to_fn_call107 108namespace stream_shared_with_ptr_of_same_lifetime {109 110void expectedClose(FILE *f, FILE **p) {111 // NOTE: Not a job of NoOwnershipChangeVisitor, but maybe this could be112 // highlighted still?113 *p = f;114}115 116void f() {117 FILE *f = fopen("input.txt", "w"); // expected-note{{Stream opened here}}118 FILE *p = NULL;119 if (!f) // expected-note{{'f' is non-null}}120 // expected-note@-1{{Taking false branch}}121 return;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_lifetime126 127namespace stream_passed_into_fn_that_doesnt_intend_to_free {128void expectedClose(FILE *f) {129}130 131void 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}}135 return;136 expectedClose(f);137 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_free141 142namespace stream_passed_into_fn_that_doesnt_intend_to_free2 {143void bar();144 145void expectedClose(FILE *f) {146 // Correctly realize that calling bar() doesn't mean that this function would147 // like to deallocate anything.148 bar();149}150 151void f() {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}}155 return;156 expectedClose(f);157 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_free2161 162namespace streamstate_from_closed_to_open {163 164// StreamState of the symbol changed from nothing to Allocated. We don't want to165// emit notes when the RefKind changes in the stack frame.166static FILE *fopenWrapper() {167 FILE *f = fopen("input.txt", "w"); // expected-note{{Stream opened here}}168 assert(f);169 return f;170}171void use_ret() {172 FILE *v;173 v = fopenWrapper(); // expected-note {{Calling 'fopenWrapper'}}174 // expected-note@-1{{Returning from 'fopenWrapper'}}175 176} // expected-warning{{Opened stream never closed. Potential resource leak [unix.Stream]}}177 // expected-note@-1{{Opened stream never closed. Potential resource leak}}178 179} // namespace streamstate_from_closed_to_open180