[PATCH] D63915: [analyzer][WIP] ReturnValueChecker: Model the guaranteed boolean return value of function calls

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 28 15:14:32 PDT 2019


NoQ added a comment.

Aha, nice, thanks for adding a description, it is a very good thing to do. Like, every commit should be obvious. Even though i know what's going on, nobody else does, so it's good to explain that this is for modeling certain weird LLVM-specific APIs that intentionally always return true.

I guess this checker should eventually be merged with `StdCLibraryFunctionsChecker` and such. I wonder if it's trivial to convert it to use `CallDescription`s and then extend it trivially to C++ functions. See also D54149 <https://reviews.llvm.org/D54149>. This is one more reason why i don't want to reinvent APINotes: i'm responsible for one more re-inventing. I'll see if i can generalize upon all of these.



================
Comment at: clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp:31-37
+namespace {
+struct CallTy {
+  bool TruthValue;
+  StringRef Name;
+  Optional<StringRef> Class;
+};
+}
----------------
Let's use `CallDescriptionMap<bool>` (it hasn't landed yet but it's almost there, D62441).

It should save quite some code; feel free to introduce a convenient constructor if it turns out to be hard to produce an initializer list.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp:81
+  // Create a note.
+  const NoteTag *CallTag = C.getNoteTag([Call](BugReport &BR) -> std::string {
+    SmallString<128> Msg;
----------------
Please make the note prunable, so that it didn't bring in the nested stack frame if it appears in a nested stack frame (cf. D61817) - you might need to add a new flag to `CheckerContext::getNoteTag()` to make this happen.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp:89
+
+    Out << Call->Name << "' always return "
+        << (Call->TruthValue ? "true" : "false");
----------------
"returns"


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp:98
+  SVal RetV = CE.getReturnValue();
+  Optional<DefinedOrUnknownSVal> RetDV = RetV.getAs<DefinedOrUnknownSVal>();
+
----------------
`castAs` if you're sure.

Generally it's either evaluated conservatively (so the return value is a conjured symbol) or inlined (and in this case returning an undefined value would result in a fatal warning), so return values shouldn't ever be undefined.

The only way to obtain an undefined return value is by binding it in `evalCall()`, but even then, i'd rather issue a warning immediately.


================
Comment at: clang/test/Analysis/return-value-guaranteed.cpp:20
+struct Foo { int Field; };
+bool error();
+bool problem();
----------------
`core.builtin.NoReturnFunctions` reacts on this function. You can easily see it in the explodedgraph dump, as the last sink node in `test_calls::parseFoo` is tagged with that checker. You'll have to pick a different name for testing purposes.


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

https://reviews.llvm.org/D63915





More information about the cfe-commits mailing list