Fix crash on call to __builtin_memcpy with a null pointer to an
incomplete type.

Also improve the diagnostics for similar situations.

llvm-svn: 342192
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f99d784..c0d0e45 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6191,12 +6191,12 @@
                 BuiltinOp == Builtin::BI__builtin_wmemmove;
 
     // The result of mem* is the first argument.
-    if (!Visit(E->getArg(0)) || Result.Designator.Invalid)
+    if (!Visit(E->getArg(0)))
       return false;
     LValue Dest = Result;
 
     LValue Src;
-    if (!EvaluatePointer(E->getArg(1), Src, Info) || Src.Designator.Invalid)
+    if (!EvaluatePointer(E->getArg(1), Src, Info))
       return false;
 
     APSInt N;
@@ -6209,6 +6209,20 @@
     if (!N)
       return true;
 
+    // Otherwise, if either of the operands is null, we can't proceed. Don't
+    // try to determine the type of the copied objects, because there aren't
+    // any.
+    if (!Src.Base || !Dest.Base) {
+      APValue Val;
+      (!Src.Base ? Src : Dest).moveInto(Val);
+      Info.FFDiag(E, diag::note_constexpr_memcpy_null)
+          << Move << WChar << !!Src.Base
+          << Val.getAsString(Info.Ctx, E->getArg(0)->getType());
+      return false;
+    }
+    if (Src.Designator.Invalid || Dest.Designator.Invalid)
+      return false;
+
     // We require that Src and Dest are both pointers to arrays of
     // trivially-copyable type. (For the wide version, the designator will be
     // invalid if the designated object is not a wchar_t.)