Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorEgor Zhdan <e_zhdan@apple.com>2022-03-11 18:57:01 +0300
committerEgor Zhdan <e_zhdan@apple.com>2022-03-14 15:47:30 +0300
commit6ca2f1938f96a71abdecdd96508f48e4d20a5694 (patch)
tree1dfca4dbc44fc8dcdf692be23799f6a32a84f2ce /clang
parent8896c36624b2eb848b892da2d29eb7a1a41bcc0e (diff)
[Clang][Sema] Avoid crashing for `__builtin_memcpy_inline` with an array argument
This change teaches the Sema logic for `__builtin_memcpy_inline` to implicitly convert arrays passed as arguments to pointers, similarly to regular `memcpy`. This code will no longer cause a compiler crash: ``` void f(char *p) { char s[1] = {0}; __builtin_memcpy_inline(p, s, 1); } ``` rdar://88147527 Differential Revision: https://reviews.llvm.org/D121475
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp11
-rw-r--r--clang/test/Sema/builtins-memcpy-inline.cpp6
2 files changed, 17 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2bd0d113fc99..2d14019cdbf1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1943,6 +1943,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
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
index 81b11fc021ff..30bc636c7839 100644
--- a/clang/test/Sema/builtins-memcpy-inline.cpp
+++ b/clang/test/Sema/builtins-memcpy-inline.cpp
@@ -36,3 +36,9 @@ void test_memcpy_inline_template(void *dst, const void *src) {
// 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);
+}