[clang] [clang][analyzer] Support `fputc` in StreamChecker (PR #71518)

Balázs Kéri via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 8 08:23:58 PST 2023


================
@@ -268,3 +285,41 @@ void error_indeterminate_feof2(void) {
   }
   fclose(F);
 }
+
+void error_indeterminate_feof3(void) {
+  FILE *F = fopen("file", "r+");
+  if (!F)
+    return;
+  char Buf[10];
+  if (fread(Buf, 1, 10, F) < 10) {
+    if (feof(F)) {
+      // error is feof, should be non-indeterminate
+      fputc(';', F); // no warning
+    }
+    if (ferror(F)) {
+      fputc('=', F); // expected-warning {{might be 'indeterminate'}}
+    }
+  }
+  fclose(F);
+}
+
+void error_indeterminate_feof4(void) {
+  FILE *F = fopen("file", "r+");
+  if (!F)
+    return;
+  if (fputc('Y', F) == EOF) {
+    fputc('W', F); // expected-warning {{might be 'indeterminate'}}
+  } else {
+    fputc('H', F); // no warning
+  }
+  fclose(F);
+}
+
+void determinate_fputc(void) {
+  FILE *F = fopen("file", "r+");
+  if (!F)
+    return;
+  if (fputc('Q', F) == 'Q')
+    fputc('X', F); // no warning
+  fclose(F);
+}
----------------
balazske wrote:

This one test could be sufficient to add to this file:
```
void error_fputc(void) {
  FILE *F = tmpfile();
  if (!F)
    return;
  int Ret = fputc('X', F);
  if (Ret == EOF) {
    clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
    fputc('Y', F); // expected-warning {{might be 'indeterminate'}}
  } else {
    clang_analyzer_eval(Ret == 'X'); // expected-warning {{TRUE}}
    clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
    fputc('Y', F); // no-warning
  }
  fclose(F);
  fputc('A', F); // expected-warning {{Stream might be already closed}}
}
```

https://github.com/llvm/llvm-project/pull/71518


More information about the cfe-commits mailing list