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