When folding the size of a global scope VLA to a constant, require the array
bound to not have side effects(!). Add constant-folding support for expressions
of void type, to ensure that we can still fold ((void)0, 1) as an array bound.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146000 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 6a290a6..9b9150c 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -4333,6 +4333,37 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Void expression evaluation, primarily for a cast to void on the LHS of a
+// comma operator
+//===----------------------------------------------------------------------===//
+
+namespace {
+class VoidExprEvaluator
+  : public ExprEvaluatorBase<VoidExprEvaluator, bool> {
+public:
+  VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
+
+  bool Success(const CCValue &V, const Expr *e) { return true; }
+  bool Error(const Expr *E) { return false; }
+
+  bool VisitCastExpr(const CastExpr *E) {
+    switch (E->getCastKind()) {
+    default:
+      return ExprEvaluatorBaseTy::VisitCastExpr(E);
+    case CK_ToVoid:
+      VisitIgnoredValue(E->getSubExpr());
+      return true;
+    }
+  }
+};
+} // end anonymous namespace
+
+static bool EvaluateVoid(const Expr *E, EvalInfo &Info) {
+  assert(E->isRValue() && E->getType()->isVoidType());
+  return VoidExprEvaluator(Info).Visit(E);
+}
+
+//===----------------------------------------------------------------------===//
 // Top level Expr::EvaluateAsRValue method.
 //===----------------------------------------------------------------------===//
 
@@ -4383,6 +4414,9 @@
     if (!EvaluateRecord(E, LV, Info.CurrentCall->Temporaries[E], Info))
       return false;
     Result = Info.CurrentCall->Temporaries[E];
+  } else if (E->getType()->isVoidType()) {
+    if (!EvaluateVoid(E, Info))
+      return false;
   } else
     return false;