[PATCH] D46648: [SimplifyLibcalls] Optimize string concats using s(n)printf

Dávid Bolvanský via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 9 10:42:44 PDT 2018


xbolva00 added inline comments.


================
Comment at: lib/Transforms/Utils/SimplifyLibCalls.cpp:1841
 
+  // sprintf(buf, "%s%s", buf, str) -> strcat(buf, str)
+  if (FormatStr == "%s%s" && CI->getNumArgOperands() == 4) {
----------------
lebedev.ri wrote:
> ```
> PRINTF(3)
> 
> <...>
> 
> NOTES
>        Some programs imprudently rely on code such as the following
> 
>            sprintf(buf, "%s some further text", buf);
> 
>        to  append  text to buf.  However, the standards explicitly note that the results are undefined if source and destination buffers overlap when calling sprintf(), snprintf(), vsprintf(), and vsnprintf().  Depending on the version of gcc(1) used, and the com‐
>        piler options employed, calls such as the above will not produce the expected results.
> 
>        The glibc implementation of the functions snprintf() and vsnprintf() conforms to the C99 standard, that is, behaves as described above, since glibc version 2.1.  Until glibc 2.0.6, they would return -1 when the output was truncated.
> ```
char buf[20] = "hello ";
sprintf(buf, "%s%s", buf, "world");
puts(buf);

No build warnings, and maybe they say that undefined results but I always get the correct results.
I hit no problems when trying these codes and transformations.

I am not sure why would this "possibly undefined results from sprintf" case should block this transformation. E.g. we perform many optimizations just because of UB... But sure, suggestions welcome.

Eli? 
@efriedma 


Repository:
  rL LLVM

https://reviews.llvm.org/D46648





More information about the llvm-commits mailing list