https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112783
Jiang ChuanGang <jiangchuanganghw at outlook dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jiangchuanganghw at outlook dot co | |m --- Comment #9 from Jiang ChuanGang <jiangchuanganghw at outlook dot com> --- (In reply to Andrew Pinski from comment #3) > The problem is not in GCC but rather a bad assumption on the code part. > > Basically we have: > > memcpy(nbuf, name, nlen); > ... > > > if (!name) > ... > > > But the check after a memcpy can be removed as passing a null pointer to > memcpy is undefined even if nlen is 0 here. > > > This patch to the sources fixes the issue for me: > ``` > diff --git a/libxo/libxo.c b/libxo/libxo.c > index 916a111..ea71723 100644 > --- a/libxo/libxo.c > +++ b/libxo/libxo.c > @@ -4300,7 +4300,8 @@ xo_format_value (xo_handle_t *xop, const char *name, > ssize_t nlen, > if ((xsp->xs_flags & (XSF_EMIT | XSF_EMIT_KEY)) > || !(xsp->xs_flags & XSF_EMIT_LEAF_LIST)) { > char nbuf[nlen + 1]; > - memcpy(nbuf, name, nlen); > + if (name) > + memcpy(nbuf, name, nlen); > nbuf[nlen] = '\0'; > > ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT_LEAF_LIST); > @@ -4324,7 +4325,8 @@ xo_format_value (xo_handle_t *xop, const char *name, > ssize_t nlen, > > } else if (!(xsp->xs_flags & XSF_EMIT_KEY)) { > char nbuf[nlen + 1]; > - memcpy(nbuf, name, nlen); > + if (name) > + memcpy(nbuf, name, nlen); > nbuf[nlen] = '\0'; > > ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT); > @@ -4342,7 +4344,8 @@ xo_format_value (xo_handle_t *xop, const char *name, > ssize_t nlen, > if ((xsp->xs_flags & XSF_EMIT_LEAF_LIST) > || !(xsp->xs_flags & XSF_EMIT)) { > char nbuf[nlen + 1]; > - memcpy(nbuf, name, nlen); > + if (name) > + memcpy(nbuf, name, nlen); > nbuf[nlen] = '\0'; > > ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT); > > ``` I've encountered the same bug, and your solution does fix it. But strangely enough, I can't reproduce it with code like the following. The inevitable condition of this bug still puzzles me. Do you have any thoughts on this. #include <stdio.h> #include <string.h> static const char *xo_xml_leader_len(const char *name, int len) { if (name == NULL || name[0] == '_') return ""; return "_"; } void test() { char *name = NULL; int len = 0; char mbuf[len + 1]; memcpy(mbuf, name, len); mbuf[len] = '\0'; const char *leader = xo_xml_leader_len(name, len); printf("leader: %s", leader); } int main() { test(); return 0; }