[PATCH] D78374: [Analyzer][StreamChecker] Added evaluation of fread and fwrite.

Balázs Kéri via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 21 00:30:32 PDT 2020


balazske added a comment.

Finally I had to make the decision to remove the `ErrorKindTy` enum and use boolean flags instead for every possible error (including no error). This is needed because we do not know always what error is possible if it is "unknown". It could be determined from the last operation but now not any more. The documentation for `fread` says that if 0 is passed as the size or count argument the function returns zero and does not change the state. So the error state before `fread` remains active. The new design is to have bool values for every error kind (**feof** and **ferror** and a no-error state) so multiple can be active in a state to indicate that more than one error state is possible. If no-error or **feof** is possible these flags are turned on. If we need to know in such a state if the stream is in **EOF** a state split is needed to handle both cases (one with **EOF** and one with no-error). This split must be done in the pre-call handler, for example if we want a warning that the operation is not safe to use in **EOF** state. (But in this case really no split is needed, only clear the EOF flag and make a warning.)

We can have another approach if we do not set return values of the functions at all, instead save the symbol of the function and determine the returned value later from the constraints actually applied on it. This may save state splits, but only until a condition is encountered that checks for the function's return value.

  int rc = fread(buf, size, count, fp);
  if (rc  < count) {
    int eof = feof(fp);
  }

In this code if the `fread` has no concrete value set, the `if` would result in state split to `rc < count` and `rc >= count`. If the `fread` sets the return value the same split is done at `fread` but not at the `if`. If there is no such `if` or only later, this saves some state splits. In the first case the possible error state of the stream may be hard to determine because it depends on the things that were done before the `fread` call too. (We can save the symbol of `fread` and `count` and ask at a later point if the condition `fread` < `count` is true to get if `fread` has failed. But need to know additionally if `count` or `size` was zero and if yes, use a previous error state.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78374





More information about the cfe-commits mailing list