sprintf(buf, "%s%s", buf, str) -> strcat(buf, str)
snprintf(buf, n, "%s%s", buf, str) -> strncat(buf, str, n)
Differential D46648
[SimplifyLibcalls] Optimize string concats using s(n)printf Authored by xbolva00 on May 9 2018, 10:17 AM.
Details
Diff Detail
Event Timeline
Comment Actions Yes, we can do anything if we prove the code has undefined behavior, but I'm not sure why we would prefer a call to strncat over "unreachable". Comment Actions "unreachable" is emitted when (in terms of this transformation)? Comment Actions If your results appear to be "correct", you're just getting lucky that your particular combination of compiler and C library don't do something else. We should probably just add clang -Wformat warning, rather than try to optimize it in SimplifyLibCalls. Comment Actions -Wformat does not handle it. UBsan.. I tried but I got some error on my system Anyway ok, I will close this. Comment Actions If you're not planning to move forward with the diff, it's better to abandon it rather than close it. Close usually implies it was committed. Comment Actions I am just wondering... snprintf(buf , n, "some data %s", buf) is UB.. Eli? Comment Actions The C standard is very clear: "If copying takes place between objects that overlap, the behavior is undefined." There is no exception for format strings which start with %s. | ||||||||||||
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.