[analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check
authorVince Bridgers <vince.a.bridgers@gmail.com>
Sun, 29 Mar 2020 12:48:26 +0000 (07:48 -0500)
committereinvbri <vince.a.bridgers@ericsson.com>
Mon, 30 Mar 2020 19:13:08 +0000 (14:13 -0500)
Summary:
This check was causing a crash in a test case where the 0th argument was
uninitialized ('Assertion `T::isKind(*this)' at line SVals.h:104). This
was happening since the argument was actually undefined, but the castAs
assumes the value is DefinedOrUnknownSVal.

The fix appears to be simply to check for an undefined value and skip
the check allowing the uninitalized value checker to detect the error.

I included a test case that I verified to produce the negative case
prior to the fix, and passes with the fix.

Reviewers: martong, NoQ

Subscribers: xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, Charusso, ASDenysPetrov, baloghadamsoftware, dkrupp, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77012

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/test/Analysis/std-c-library-functions.c

index cd257ff..6e5f5f8 100644 (file)
@@ -190,6 +190,9 @@ class StdLibraryFunctionsChecker
     ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                           const Summary &Summary) const override {
       SVal V = getArgSVal(Call, getArgNo());
+      if (V.isUndef())
+        return State;
+
       DefinedOrUnknownSVal L = V.castAs<DefinedOrUnknownSVal>();
       if (!L.getAs<Loc>())
         return State;
index 3f700a7..a275ea6 100644 (file)
@@ -89,6 +89,14 @@ void test_fread_fwrite(FILE *fp, int *buf) {
   clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}
 }
 
+void test_fread_uninitialized(void) {
+  void *ptr;
+  size_t sz;
+  size_t nmem;
+  FILE *fp;
+  (void)fread(ptr, sz, nmem, fp); // expected-warning {{1st function call argument is an uninitialized value}}
+}
+
 ssize_t getline(char **, size_t *, FILE *);
 void test_getline(FILE *fp) {
   char *line = 0;