<div dir="ltr">Got it. There are two places (one in clang, one in llvm) where being named `memcpy' is a free pass for a function, independently of the presence of an actual definition. The attached patch makes sure that if a function named after an intrinsic has a body, calls to that function are not lowered to intrinsics. It has the (expected) side effect of getting a behavior closer to GCC wrt. -D_FORTIFY_SOURCE=n, and wrt. using function named after famous ones.<div><br></div><div>Do we want to go that way?</div><div><div><br></div><div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Dec 4, 2019 at 10:23 AM Serge Guelton <<a href="mailto:sguelton@redhat.com">sguelton@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>> So I would conclude that the builtin works just fine, but the issue is </div>> with the exact rules for when and how the inline function is preferred <br>> over the externally available version.<div><br></div><div>Fascinating. I can elaborate a bit more based on <a href="https://godbolt.org/z/EZGfqd" target="_blank">https://godbolt.org/z/EZGfqd</a> : there's a special handling for memcpy (and probably other similar functions) in clang that prevents him from considering the inline version.I'll dig in clang source to find out more about this behavior. <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Dec 4, 2019 at 9:11 AM Martin Storsjö <<a href="mailto:martin@martin.st" target="_blank">martin@martin.st</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, 4 Dec 2019, Serge Guelton via llvm-dev wrote:<br>
<br>
> > Are you sure you've diagnosed the issue correctly? __builtin___memcpy_chk<br>
> works correctly, as far as I know.<br>
> 100% sure. Let's have a look at the output of<br>
> <br>
>   #include <string.h><br>
>   static char dest[10];<br>
>   char* square(int n) {<br>
>     memcpy(dest, "hello", n);<br>
>     return dest;<br>
>   }<br>
> <br>
> compiled with -D_FORTIFY_SOURCE=1 -O1 : <a href="https://godbolt.org/z/UvABWp" rel="noreferrer" target="_blank">https://godbolt.org/z/UvABWp</a><br>
> <br>
> Clang issues a call to memcpy, while gcc issues a call to __memcpy_chk.<br>
> The call to __memcpy_chk performs extra runtime checks memcpy doesn't,<br>
> and clang doesn't generate the extra checks inline either. This is a<br>
> separate<br>
> concern from the accuracy of __builtin_object_size, just a different runtime<br>
> behavior.<br>
> <br>
> Clang could generate the call to __memcpy_chk if its declaration is<br>
> available, which is the case for the glibc.<br>
<br>
No, this doesn't seem to be the case.<br>
<br>
I expanded your testcase by removing the string.h include and replacing it <br>
with the relevant bits of it:<br>
<br>
<a href="https://godbolt.org/z/NKUQbW" rel="noreferrer" target="_blank">https://godbolt.org/z/NKUQbW</a><br>
<br>
The regular call to memcpy ends up without the extra safety checks and <br>
just generates a call to memcpy. But if I call __builtin___memcpy_chk <br>
directly, it does generate a call to __memcpy_chk.<br>
<br>
So I would conclude that the builtin works just fine, but the issue is <br>
with the exact rules for when and how the inline function is preferred <br>
over the externally available version.<br>
<br>
I added a "#define VISIBIILTY extern" to ease testing and changing it. If <br>
you change that into static, you'll see that the inline version of the <br>
function actually ends up used, and it does generate a call to <br>
__memcpy_chk even there.<br>
<br>
And this does seem to show that __builtin_object_size does work fine from <br>
within an inlined function now, contrary to my earlier comments.<br>
<br>
// Martin<br>
</blockquote></div>
</blockquote></div>