[PATCH] D106262: [clang][analyzer] Use generic note tag in alpha.unix.Stream .

Balázs Kéri via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 17 02:29:36 PDT 2021


balazske added a comment.

> I'd like to test cases where the very same function call gets a different note message depending on the BugType:

These tests are doing this:

  void check_indeterminate_notes_fseek_no_feof_no_ferror() {
    FILE *F;
    char Buf[10];
    F = fopen("foo1.c", "r");
    if (!F) // expected-note {{Taking false branch}} expected-note {{'F' is non-null}}
      return;
    fseek(F, 1, SEEK_SET);      // expected-note {{Assuming this stream operation fails and leaves the file position indeterminate}}
    if (!ferror(F) && !feof(F)) // expected-note {{The error flag is not set on the stream}} expected-note {{The end-of-file flag is not set on the stream}}
                                // expected-note at -1 {{Taking true branch}} expected-note at -1 {{Left side of '&&' is true}}
      fread(Buf, 1, 1, F);      // expected-warning{{File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior}}
    // expected-note at -1{{File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior}}
    fclose(F);
  }
  
  void check_feof_notes_fseek() {
    FILE *F;
    char Buf[10];
    F = fopen("foo1.c", "r");
    if (!F) // expected-note {{Taking false branch}} expected-note {{'F' is non-null}}
      return;
    fseek(F, 1, SEEK_SET); // expected-note {{Assuming stream reaches end-of-file here}}
    if (feof(F))           // expected-note{{The end-of-file flag is set on the stream}} 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 at -1 {{Read function called when stream is in EOF state. Function has no effect}}
    fclose(F);
  }

Why is the last test not sufficient and I should use instead this test?

  void check_notes_fseek_caused_feof() {
    FILE *F;
    char Buf[10];
    F = fopen("foo1.c", "r");
    if (!F) // expected-note {{Taking false branch}} expected-note {{'F' is non-null}}
      return;
    fseek(F, 1, SEEK_SET); // expected-note {{Assuming stream reaches end-of-file here}}
    if (ferror(F)) { // expected-note {{The error flag is not set on the stream}}
                   // expected-note at -1 {{Taking false branch}}
      fclose(F);
      return;
    }
    StreamTesterChecker_clear_indeterminate_file_position(F);
    fread(Buf, 1, 1, F); // expected-warning{{Read function called when stream is in EOF state. Function has no effect}}
    // expected-note at -1{{Read function called when stream is in EOF state. Function has no effect}}
    fclose(F);
  }

In the first case before the `fread` the EOF bit is on. In the second there are 2 possibilities, one is when `fseek` did not fail at all, other when it failed and then EOF is on. This are really 3 execution paths: `fseek` did not fail, `fseek` failed with EOF, and `fseek` failed without FEOF or FERROR but leaves indeterminate position (that is cleared, so we get the same state as after success).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D106262/new/

https://reviews.llvm.org/D106262



More information about the cfe-commits mailing list