]> granicus.if.org Git - clang/commitdiff
[analyzer] Fix a rare crash for valist check.
authorGabor Horvath <xazax.hun@gmail.com>
Mon, 13 Mar 2017 12:48:26 +0000 (12:48 +0000)
committerGabor Horvath <xazax.hun@gmail.com>
Mon, 13 Mar 2017 12:48:26 +0000 (12:48 +0000)
It looks like on some host-triples the result of a valist related expr can be
a LazyCompoundVal. Handle that case in the check.

Patch by Abramo Bagnara!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297619 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/ValistChecker.cpp
test/Analysis/valist-as-lazycompound.c [new file with mode: 0644]
test/Analysis/valist-uninitialized-no-undef.c

index 9515c67a4d2f93ccd956a23d81e359322d6fe0dd..d12ba625807391e74f22db7fa1af91c0e6dabe7e 100644 (file)
@@ -165,11 +165,8 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
 const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
                                                   bool &IsSymbolic,
                                                   CheckerContext &C) const {
-  // FIXME: on some platforms CallAndMessage checker finds some instances of
-  // the uninitialized va_list usages. CallAndMessage checker is disabled in
-  // the tests so they can verify platform independently those issues. As a
-  // side effect, this check is required here.
-  if (SV.isUnknownOrUndef())
+  const MemRegion *Reg = SV.getAsRegion();
+  if (!Reg)
     return nullptr;
   // TODO: In the future this should be abstracted away by the analyzer.
   bool VaListModelledAsArray = false;
@@ -178,7 +175,6 @@ const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
     VaListModelledAsArray =
         Ty->isPointerType() && Ty->getPointeeType()->isRecordType();
   }
-  const MemRegion *Reg = SV.getAsRegion();
   if (const auto *DeclReg = Reg->getAs<DeclRegion>()) {
     if (isa<ParmVarDecl>(DeclReg->getDecl()))
       Reg = C.getState()->getSVal(SV.castAs<Loc>()).getAsRegion();
diff --git a/test/Analysis/valist-as-lazycompound.c b/test/Analysis/valist-as-lazycompound.c
new file mode 100644 (file)
index 0000000..2fbd4cb
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 -triple gcc-linaro-arm-linux-gnueabihf -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// expected-no-diagnostics
+
+typedef unsigned int size_t;
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+extern int vsprintf(char *__restrict __s,
+                    const char *__restrict __format, __gnuc_va_list
+                                                         __arg);
+
+void _dprintf(const char *function, int flen, int line, int level,
+             const char *prefix, const char *fmt, ...) {
+  char raw[10];
+  int err;
+  va_list ap;
+
+  __builtin_va_start(ap, fmt);
+  err = vsprintf(raw, fmt, ap);
+  __builtin_va_end(ap);
+}
index edcdc992d5941051515cae098d4cc3e2b18ea747..528ac86c142130161b5002daa8ae22560970023c 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-for-valist.h"