[Bug tree-optimization/124754] [15 Regression] ICE with new std::string exports: during GIMPLE pass: strlen since r15-5595
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 1 20:53:14 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124754
--- Comment #26 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-15 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:38dab5eac03fff96aae72612bc8e76c40381339b
commit r15-11212-g38dab5eac03fff96aae72612bc8e76c40381339b
Author: Jakub Jelinek <jakub@redhat.com>
Date: Fri Apr 3 20:55:26 2026 +0200
strlen: Fix up memcpy/strcpy/strcat handling [PR124754]
The following testcase ICEs because it tries to use a freed strinfo.
strinfo uses refcounting and vectors of pointers to those are either shared
in between bbs or unshared when some later bb needs to modify something.
The ICE is due to the second memcpy handling. Since r10-5451 it first
calls get_stridx on dst (&a), then get_strinfo with the returned index and
then get_stridx on src (&a + 24). &a has been referenced earlier and
the pass knows some details on its string length (let's ignore that the
testcase invokes UB for now, I think it can happen even on valid code,
just haven't managed to adjust the testcase, but supposedly the unreduced
original is valid), so the strinfo is shared with other bbs.
WHen get_stridx is called for &a + 24, it sees it doesn't know anything
about that yet and wants to create a strinfo for it. But related strinfos
are chained, so &a's next should be &a + 24 in this testcase, that means
we need to unshare the &a strinfo so that we can modify it while keeping
the one entry used by earlier bbs unmodified. The problem is that
handle_builtin_memcpy called get_strinfo before this, so it got hands on
the old still not unshared strinfo for &a and because it isn't refreshed
after the get_stridx call by another get_strinfo call, we try to unshare
it again and break the refcounting.
So, basically for calls which call get_stridx twice, we need top make sure
we do both get_stridx calls before the first get_strinfo call, or repeat
get_strinfo after the second get_stridx call.
In handle_builtin_memcpy it used to be right and got broken by r10-5451,
but I'm in strcpy/strcat handling I've screwed it up since the pass was
added.
Fixed thusly.
2026-04-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/124754
* tree-ssa-strlen.cc (strlen_pass::handle_builtin_strcpy): Make
sure both get_stridx calls are done before first get_strinfo call.
(strlen_pass::handle_builtin_memcpy): Likewise.
(strlen_pass::handle_builtin_strcat): Likewise.
* g++.dg/tree-ssa/strlenopt-3.C: New test.
Reviewed-by: Jeffrey Law <jeffrey.law@oss.qualcomm.com>
(cherry picked from commit 0ce6f1d493e2511c745621fb14b93fb4e54c0b06)
More information about the Gcc-bugs
mailing list