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 <[email protected]>: https://gcc.gnu.org/g:38dab5eac03fff96aae72612bc8e76c40381339b commit r15-11212-g38dab5eac03fff96aae72612bc8e76c40381339b Author: Jakub Jelinek <[email protected]> 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 <[email protected]> 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 <[email protected]> (cherry picked from commit 0ce6f1d493e2511c745621fb14b93fb4e54c0b06)
