[PATCH] D121475: [Clang][Sema] Avoid crashing for `__builtin_memcpy_inline` with an array argument

Egor Zhdan via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 11 10:02:02 PST 2022


egorzhdan created this revision.
egorzhdan added a reviewer: gchatelet.
Herald added a project: All.
egorzhdan requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121475

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


Index: clang/test/Sema/builtins-memcpy-inline.cpp
===================================================================
--- clang/test/Sema/builtins-memcpy-inline.cpp
+++ 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);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ 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 ArgArrayConversion = [&](unsigned Arg) {
+      ExprResult ArgExpr =
+          DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg));
+      if (ArgExpr.isInvalid())
+        return true;
+      TheCall->setArg(Arg, ArgExpr.get());
+      return false;
+    };
+
+    if (ArgArrayConversion(0) || ArgArrayConversion(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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121475.414688.patch
Type: text/x-patch
Size: 1412 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220311/5827268a/attachment.bin>


More information about the cfe-commits mailing list