r331562 - [analyzer] pr36458: Fix retrieved value cast for symbolic void pointers.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Fri May 4 15:11:12 PDT 2018


Author: dergachev
Date: Fri May  4 15:11:12 2018
New Revision: 331562

URL: http://llvm.org/viewvc/llvm-project?rev=331562&view=rev
Log:
[analyzer] pr36458: Fix retrieved value cast for symbolic void pointers.

C allows us to write any bytes into any memory region. When loading weird bytes
from memory regions of known types, the analyzer is required to make sure that
the loaded value makes sense by casting it to an appropriate type.

Fix such cast for loading values that represent void pointers from non-void
pointer type places.

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

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
    cfe/trunk/test/Analysis/casts.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp?rev=331562&r1=331561&r2=331562&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp Fri May  4 15:11:12 2018
@@ -378,6 +378,20 @@ SVal StoreManager::CastRetrievedVal(SVal
   if (castTy.isNull() || V.isUnknownOrUndef())
     return V;
 
+  // When retrieving symbolic pointer and expecting a non-void pointer,
+  // wrap them into element regions of the expected type if necessary.
+  // SValBuilder::dispatchCast() doesn't do that, but it is necessary to
+  // make sure that the retrieved value makes sense, because there's no other
+  // cast in the AST that would tell us to cast it to the correct pointer type.
+  // We might need to do that for non-void pointers as well.
+  // FIXME: We really need a single good function to perform casts for us
+  // correctly every time we need it.
+  if (castTy->isPointerType() && !castTy->isVoidPointerType())
+    if (const auto *SR = dyn_cast_or_null<SymbolicRegion>(V.getAsRegion()))
+      if (SR->getSymbol()->getType().getCanonicalType() !=
+          castTy.getCanonicalType())
+        return loc::MemRegionVal(castRegion(SR, castTy));
+
   return svalBuilder.dispatchCast(V, castTy);
 }
 

Modified: cfe/trunk/test/Analysis/casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=331562&r1=331561&r2=331562&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/casts.c (original)
+++ cfe/trunk/test/Analysis/casts.c Fri May  4 15:11:12 2018
@@ -149,3 +149,25 @@ void multiDimensionalArrayPointerCasts()
 
   clang_analyzer_eval(*((char *)y1) == *((char *) y3)); // expected-warning{{TRUE}}
 }
+
+void *getVoidPtr();
+
+void testCastVoidPtrToIntPtrThroughIntTypedAssignment() {
+  int *x;
+  (*((int *)(&x))) = (int)getVoidPtr();
+  *x = 1; // no-crash
+}
+
+void testCastUIntPtrToIntPtrThroughIntTypedAssignment() {
+  unsigned u;
+  int *x;
+  (*((int *)(&x))) = (int)&u;
+  *x = 1;
+  clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}
+}
+
+void testCastVoidPtrToIntPtrThroughUIntTypedAssignment() {
+  int *x;
+  (*((int *)(&x))) = (int)(unsigned *)getVoidPtr();
+  *x = 1; // no-crash
+}




More information about the cfe-commits mailing list