r183359 - [analyzer] Fix a crash that occurs when processing an rvalue array.

Anna Zaks ganna at apple.com
Wed Jun 5 17:19:36 PDT 2013


Author: zaks
Date: Wed Jun  5 19:19:36 2013
New Revision: 183359

URL: http://llvm.org/viewvc/llvm-project?rev=183359&view=rev
Log:
[analyzer] Fix a crash that occurs when processing an rvalue array.

When processing ArrayToPointerDecay, we expect the array to be a location, not a LazyCompoundVal.
Special case the rvalue arrays by using a location to represent them. This case is handled similarly
elsewhere in the code.

Fixes PR16206.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/SemaTemplate/array-to-pointer-decay.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=183359&r1=183358&r2=183359&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jun  5 19:19:36 2013
@@ -1724,7 +1724,24 @@ void ExprEngine::VisitMemberExpr(const M
 
   FieldDecl *field = cast<FieldDecl>(Member);
   SVal L = state->getLValue(field, baseExprVal);
-  if (M->isGLValue()) {
+
+  if (M->isGLValue() || M->getType()->isArrayType()) {
+
+    // We special case rvalue of array type because the analyzer cannot reason
+    // about it, since we expect all regions to be wrapped in Locs. So we will
+    // treat these as lvalues assuming that they will decay to pointers as soon
+    // as they are used. Below
+    if (!M->isGLValue()) {
+      assert(M->getType()->isArrayType());
+      const ImplicitCastExpr *PE =
+        dyn_cast<ImplicitCastExpr>(Pred->getParentMap().getParent(M));
+      if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
+        assert(false &&
+               "We assume that array is always wrapped in ArrayToPointerDecay");
+        L = UnknownVal();
+      }
+    }
+
     if (field->getType()->isReferenceType()) {
       if (const MemRegion *R = L.getAsRegion())
         L = state->getSVal(R);

Modified: cfe/trunk/test/SemaTemplate/array-to-pointer-decay.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/array-to-pointer-decay.cpp?rev=183359&r1=183358&r2=183359&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/array-to-pointer-decay.cpp (original)
+++ cfe/trunk/test/SemaTemplate/array-to-pointer-decay.cpp Wed Jun  5 19:19:36 2013
@@ -24,3 +24,15 @@ template <typename Type> static bool san
   return !c->start;
 }
 bool closure = sanitize<int>();
+
+// PR16206
+typedef struct {
+	char x[4];
+} chars;
+
+chars getChars();
+void use(char *);
+
+void test() {
+	use(getChars().x);
+}





More information about the cfe-commits mailing list