[clang] 6ca2f19 - [Clang][Sema] Avoid crashing for `__builtin_memcpy_inline` with an array argument

Egor Zhdan via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 14 05:47:37 PDT 2022


Author: Egor Zhdan
Date: 2022-03-14T12:47:30Z
New Revision: 6ca2f1938f96a71abdecdd96508f48e4d20a5694

URL: https://github.com/llvm/llvm-project/commit/6ca2f1938f96a71abdecdd96508f48e4d20a5694
DIFF: https://github.com/llvm/llvm-project/commit/6ca2f1938f96a71abdecdd96508f48e4d20a5694.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/Sema/SemaChecking.cpp
    clang/test/Sema/builtins-memcpy-inline.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2bd0d113fc992..2d14019cdbf18 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 81b11fc021fff..30bc636c78393 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);
+}


        


More information about the cfe-commits mailing list