diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1943,6 +1943,17 @@ case Builtin::BI__builtin_nontemporal_store: return SemaBuiltinNontemporalOverloaded(TheCallResult); case Builtin::BI__builtin_memcpy_inline: { + auto ArgArrayConversionFailed = [&](unsigned Arg) { + ExprResult ArgExpr = + DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg)); + if (ArgExpr.isInvalid()) + return true; + TheCall->setArg(Arg, ArgExpr.get()); + return false; + }; + + if (ArgArrayConversionFailed(0) || ArgArrayConversionFailed(1)) + return true; clang::Expr *SizeOp = TheCall->getArg(2); // We warn about copying to or from `nullptr` pointers when `size` is // greater than 0. When `size` is value dependent we cannot evaluate its diff --git a/clang/test/Sema/builtins-memcpy-inline.cpp b/clang/test/Sema/builtins-memcpy-inline.cpp --- a/clang/test/Sema/builtins-memcpy-inline.cpp +++ b/clang/test/Sema/builtins-memcpy-inline.cpp @@ -36,3 +36,9 @@ // we do not try to evaluate size in non intantiated templates. __builtin_memcpy_inline(dst, src, size); } + +void test_memcpy_inline_implicit_conversion(void *ptr) { + char a[5]; + __builtin_memcpy_inline(ptr, a, 5); + __builtin_memcpy_inline(a, ptr, 5); +}