r253532 - [analyzer] Improve modeling of static initializers.

Anna Zaks via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 18 17:25:29 PST 2015


Author: zaks
Date: Wed Nov 18 19:25:28 2015
New Revision: 253532

URL: http://llvm.org/viewvc/llvm-project?rev=253532&view=rev
Log:
[analyzer] Improve modeling of static initializers.

Conversions between unrelated pointer types (e.g. char * and void *) involve
bitcasts which were not properly modeled in case of static initializers. The
patch fixes this problem.

The problem was originally spotted by Artem Dergachev. Patched by Yuri Gribov!

Differential Revision: http://reviews.llvm.org/D14652

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
    cfe/trunk/test/Analysis/inline.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=253532&r1=253531&r2=253532&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Wed Nov 18 19:25:28 2015
@@ -275,11 +275,17 @@ Optional<SVal> SValBuilder::getConstantV
 
   case Stmt::ImplicitCastExprClass: {
     const CastExpr *CE = cast<CastExpr>(E);
-    if (CE->getCastKind() == CK_ArrayToPointerDecay) {
-      Optional<SVal> ArrayVal = getConstantVal(CE->getSubExpr());
-      if (!ArrayVal)
+    switch (CE->getCastKind()) {
+    default:
+      break;
+    case CK_ArrayToPointerDecay:
+    case CK_BitCast: {
+      const Expr *SE = CE->getSubExpr();
+      Optional<SVal> Val = getConstantVal(SE);
+      if (!Val)
         return None;
-      return evalCast(*ArrayVal, CE->getType(), CE->getSubExpr()->getType());
+      return evalCast(*Val, CE->getType(), SE->getType());
+    }
     }
     // FALLTHROUGH
   }

Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=253532&r1=253531&r2=253532&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Wed Nov 18 19:25:28 2015
@@ -275,7 +275,7 @@ namespace DefaultArgs {
 
     clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
     clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
-}
+  }
 
   double defaultFloatReference(const double &i = 42) {
     return -i;
@@ -300,6 +300,13 @@ namespace DefaultArgs {
     clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
     clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
   }
+
+  const void * const void_string = "abc";
+
+  void testBitcastedString() {
+    clang_analyzer_eval(0 != void_string); // expected-warning{{TRUE}}
+    clang_analyzer_eval('b' == ((char *)void_string)[1]); // expected-warning{{TRUE}}
+  }
 }
 
 namespace OperatorNew {




More information about the cfe-commits mailing list