[PATCH] D67706: [clang][analyzer] Using CallDescription in StreamChecker.

Csaba Dabis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 29 04:33:14 PDT 2019


Charusso added a reviewer: Charusso.
Charusso requested changes to this revision.
Charusso added a comment.
This revision now requires changes to proceed.

Could you please mark resolved issues as resolved? I would like to see what we miss, and what has been done.



================
Comment at: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:61
+  using FnCheck = bool (StreamChecker::*)(const CallEvent &,
+                                          CheckerContext &) const;
+
----------------
I prefer `std::function`, because it is modern.
```
  using StreamCheck = 
      std::function<void(const StreamChecker *, const CallEvent &,
                         CheckerContext &)>;
```
I think it is fine with pointers, but at some point we need to modernize this.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:64
+  CallDescriptionMap<FnCheck> Callbacks = {
+      {{"fopen"}, &StreamChecker::evalFopen},
+      {{"tmpfile"}, &StreamChecker::evalTmpfile},
----------------
Because `evalFopen()` is basically the `OpenFileAux(Call, C);`, I think we could simplify the API by removing unnecessary one-liners so here you could write `{{"fopen"}, &StreamChecker::OpenFileAux`, that is why the `CallEvent` parameter is so generic and useful.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:99
+  Optional<ProgramStateRef> CheckNullStream(SVal SV, CheckerContext &C) const;
+  Optional<ProgramStateRef> CheckDoubleClose(const CallEvent &Call,
+                                             CheckerContext &C) const;
----------------
This `Optional` is not necessary. When the state is changed, you can rely on `CheckerContext::isDifferent()` to see whether the modeling was succeeded. Therefore you could revert the `bool` return values as well.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:117
 
-  ASTContext &Ctx = C.getASTContext();
-  if (!II_fopen)
-    II_fopen = &Ctx.Idents.get("fopen");
-  if (!II_tmpfile)
-    II_tmpfile = &Ctx.Idents.get("tmpfile");
-  if (!II_fclose)
-    II_fclose = &Ctx.Idents.get("fclose");
-  if (!II_fread)
-    II_fread = &Ctx.Idents.get("fread");
-  if (!II_fwrite)
-    II_fwrite = &Ctx.Idents.get("fwrite");
-  if (!II_fseek)
-    II_fseek = &Ctx.Idents.get("fseek");
-  if (!II_ftell)
-    II_ftell = &Ctx.Idents.get("ftell");
-  if (!II_rewind)
-    II_rewind = &Ctx.Idents.get("rewind");
-  if (!II_fgetpos)
-    II_fgetpos = &Ctx.Idents.get("fgetpos");
-  if (!II_fsetpos)
-    II_fsetpos = &Ctx.Idents.get("fsetpos");
-  if (!II_clearerr)
-    II_clearerr = &Ctx.Idents.get("clearerr");
-  if (!II_feof)
-    II_feof = &Ctx.Idents.get("feof");
-  if (!II_ferror)
-    II_ferror = &Ctx.Idents.get("ferror");
-  if (!II_fileno)
-    II_fileno = &Ctx.Idents.get("fileno");
-
-  if (FD->getIdentifier() == II_fopen) {
-    Fopen(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_tmpfile) {
-    Tmpfile(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fclose) {
-    Fclose(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fread) {
-    Fread(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fwrite) {
-    Fwrite(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fseek) {
-    Fseek(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_ftell) {
-    Ftell(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_rewind) {
-    Rewind(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fgetpos) {
-    Fgetpos(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fsetpos) {
-    Fsetpos(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_clearerr) {
-    Clearerr(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_feof) {
-    Feof(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_ferror) {
-    Ferror(C, CE);
-    return true;
-  }
-  if (FD->getIdentifier() == II_fileno) {
-    Fileno(C, CE);
-    return true;
+  return (this->*Callback)(Call, C);
+}
----------------
Why do you inject `this`?


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:137
+  return *Callback;
 }
 
----------------
I would move this tiny `identifyCall()` into `evalCall()` as the purpose of `evalCall()` is the validation of the `Callback` in this case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67706





More information about the cfe-commits mailing list