<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 3 January 2017 at 14:46, Friedman, Eli <span dir="ltr"><<a href="mailto:efriedma@codeaurora.org" target="_blank">efriedma@codeaurora.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">On 1/3/2017 2:06 PM, Richard Smith via cfe-dev wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Via <a href="https://reviews.llvm.org/D27855" rel="noreferrer" target="_blank">https://reviews.llvm.org/D2785<wbr>5</a>, LLVM is likely to gain the ability to delete null checks in callers based on __attribute__((nonnull)) on the callee. This interacts badly with glibc's choice to mark the pointer parameters of memcpy, memmove, etc. as __attribute__((nonnull)) -- it is relatively common for programs to pass a null pointer and a zero size to these functions, and in practice libc implementations accept such usage. Indeed, LLVM's lowering of @llvm.memcpy intrinsics relies on these calls working.<br>
<br>
Deleting a null pointer check on p after a memcpy(p, q, 0) call seems extremely user-hostile, and very unlikely to result in a valuable improvement to the program, so I propose that we stop lowering __attribute__((nonnull)) on these builtin library functions to the llvm nonnull attribute.<br>
<br>
(Chandler is working on a paper for the C++ committee proposing to give these functions defined behavior when given a null pointer and a zero size, but optimizing on the basis of these particular nonnull attributes seems like a bad idea regardless of the C or C++ committees' decisions.)<br>
<br>
Thoughts?<br>
</blockquote>
<br></div></div>
"memcpy, memmove, etc." seems to be hiding some details here; do you have a complete list of functions you want to special-case?  There are a lot of functions which could potentially go on that list, and some of them are POSIX or GNU extensions.<br></blockquote><div><br></div><div>The following glibc functions in <string.h> take both a pointer and a size providing an upper limit on the number of bytes that may be accessed through that pointer, and mark the pointer as __attribute__((nonnull)):</div><div><br></div><div>ISO C:</div><div>  memcpy, memmove, memset, memcmp, memchr, memrchr</div><div>  strncpy [param 1 only], strncat [param 1 only], strncmp</div><div><br></div><div>Extensions:</div><div>  strndup, memccpy, mempcpy, strnlen, bcopy, bzero, bcmp, memfrob,</div><div>  strncasecmp, strncasecmp_l [not parameter 4], stpncpy<br></div><div><br></div><div>I would be interested in covering at least the ISO C functions. I don't have strong opinions about the extensions (any code built using those is likely also compiled with GCC, and so presumably has to fix this regardless).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Why do we care about keeping these null pointer checks in particular, as opposed to providing a flag which stops the optimizer from deleting null pointer checks in general (like gcc's -fno-delete-null-pointer-check<wbr>s).</blockquote><div><br></div><div>Deleting null checks when we can prove a pointer logically cannot possibly be null is still useful -- for instance, deleting a null check after the pointer was already passed to strlen, or when it's the address of a local variable, both seem fine.</div></div></div></div>