[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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183359 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 627e010..7a0ba64 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1724,7 +1724,24 @@
 
   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);
diff --git a/test/SemaTemplate/array-to-pointer-decay.cpp b/test/SemaTemplate/array-to-pointer-decay.cpp
index 26d277d..dcf0901 100644
--- a/test/SemaTemplate/array-to-pointer-decay.cpp
+++ b/test/SemaTemplate/array-to-pointer-decay.cpp
@@ -24,3 +24,15 @@
   return !c->start;
 }
 bool closure = sanitize<int>();
+
+// PR16206
+typedef struct {
+	char x[4];
+} chars;
+
+chars getChars();
+void use(char *);
+
+void test() {
+	use(getChars().x);
+}