@@ -1723,6 +1723,32 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC,
17231723 llvm_unreachable (" Unsupported vector reduce builtin" );
17241724}
17251725
1726+ static bool interp__builtin_memcpy (InterpState &S, CodePtr OpPC,
1727+ const InterpFrame *Frame,
1728+ const Function *Func, const CallExpr *Call) {
1729+ assert (Call->getNumArgs () == 3 );
1730+ Pointer DestPtr = getParam<Pointer>(Frame, 0 );
1731+ const Pointer &SrcPtr = getParam<Pointer>(Frame, 1 );
1732+ const APSInt &Size =
1733+ peekToAPSInt (S.Stk , *S.getContext ().classify (Call->getArg (2 )));
1734+ assert (!Size.isSigned () && " memcpy and friends take an unsigned size" );
1735+
1736+ if (DestPtr.isDummy () || SrcPtr.isDummy ())
1737+ return false ;
1738+
1739+ // If the size is zero, we treat this as always being a valid no-op.
1740+ if (Size.isZero ()) {
1741+ S.Stk .push <Pointer>(DestPtr);
1742+ return true ;
1743+ }
1744+
1745+ if (!DoBitCastPtr (S, OpPC, SrcPtr, DestPtr))
1746+ return false ;
1747+
1748+ S.Stk .push <Pointer>(DestPtr);
1749+ return true ;
1750+ }
1751+
17261752bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
17271753 const CallExpr *Call, uint32_t BuiltinID) {
17281754 const InterpFrame *Frame = S.Current ;
@@ -2173,6 +2199,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
21732199 return false ;
21742200 break ;
21752201
2202+ case Builtin::BI__builtin_memcpy:
2203+ if (!interp__builtin_memcpy (S, OpPC, Frame, F, Call))
2204+ return false ;
2205+ break ;
2206+
21762207 default :
21772208 S.FFDiag (S.Current ->getLocation (OpPC),
21782209 diag::note_invalid_subexpr_in_const_expr)
0 commit comments