[analyzer] Relax an assertion in VisitLvalArraySubscriptExpr

The analyzer thinks that ArraySubscriptExpr cannot be an r-value (ever).
However, it can be in some corner cases. Specifically, C forbids expressions
of unqualified void type from being l-values.

Note, the analyzer will keep modeling the subscript expr as an l-value. The
analyzer should be treating void* as a char array
(https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Pointer-Arith.html).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228249 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 4699df8..5cdb7eb 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1901,6 +1901,9 @@
   getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
 
   StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx);
+  assert(A->isGLValue() ||
+          (!AMgr.getLangOpts().CPlusPlus &&
+           A->getType().isCForbiddenLValueType()));
 
   for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
                                  ei = checkerPreStmt.end(); it != ei; ++it) {
@@ -1909,7 +1912,6 @@
     SVal V = state->getLValue(A->getType(),
                               state->getSVal(Idx, LCtx),
                               state->getSVal(Base, LCtx));
-    assert(A->isGLValue());
     Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), nullptr,
                       ProgramPoint::PostLValueKind);
   }
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index c22f979..28e09ad 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -183,3 +183,19 @@
   return ((char *)&(((struct s*)0)->data_array)) - ((char *)0); // no-warning
 }
 
+int testPointerArithmeticOnVoid(void *bytes) {
+  int p = 0;
+  if (&bytes[0] == &bytes[1])
+    return 6/p; // no-warning
+  return 0;
+}
+
+int testRValueArraySubscriptExpr(void *bytes) {
+  int *p = (int*)&bytes[0];
+  *p = 0;
+  if (*(int*)&bytes[0] == 0)
+    return 0;
+  return 5/(*p); // no-warning
+}
+
+