diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2d2250771eb6e..e02104b4699e1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1679,7 +1679,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if ((ICEArguments & (1 << ArgNo)) == 0) continue; llvm::APSInt Result; - if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) + // If we don't have enough arguments, continue so we can issue better + // diagnostic in checkArgCount(...) + if (ArgNo < TheCall->getNumArgs() && + SemaBuiltinConstantArg(TheCall, ArgNo, Result)) return true; ICEArguments &= ~(1 << ArgNo); } @@ -1943,6 +1946,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_nontemporal_store: return SemaBuiltinNontemporalOverloaded(TheCallResult); case Builtin::BI__builtin_memcpy_inline: { + if (checkArgCount(*this, TheCall, 3)) + return ExprError(); auto ArgArrayConversionFailed = [&](unsigned Arg) { ExprResult ArgExpr = DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg)); diff --git a/clang/test/Sema/builtins-memcpy-inline.cpp b/clang/test/Sema/builtins-memcpy-inline.cpp index 30bc636c78393..ab0a8700a6c98 100644 --- a/clang/test/Sema/builtins-memcpy-inline.cpp +++ b/clang/test/Sema/builtins-memcpy-inline.cpp @@ -42,3 +42,8 @@ void test_memcpy_inline_implicit_conversion(void *ptr) { __builtin_memcpy_inline(ptr, a, 5); __builtin_memcpy_inline(a, ptr, 5); } + +void test_memcpy_inline_num_args(void *dst, void *src) { + __builtin_memcpy_inline(); // expected-error {{too few arguments to function call}} + __builtin_memcpy_inline(dst, src, 4, NULL); // expected-error {{too many arguments to function call}} +}