http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57230
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That case is for the if (idx > 0) { si = get_strinfo (idx); ... } block in there, and si != NULL && si->length != NULL_TREE && TREE_CODE (si->length) == INTEGER_CST is what you are looking for (together with gimple_assign_rhs1 (stmt) being non-zero INTEGER_CST. You'd just verify that si->length is bigger than 0 and if so, set si->dont_invalidate = true; But the thing is that unless it is p[0] = 'X'; store, the si in that case is say for p + 6 address rather than p + 1, so while it would keep strlen (&p[6]) valid, it would happily invalidate strlen (&p[1]) or strlen (p). So, you need to mark not to invalidate also the related string lengths if any. This could be done say by adjust_related_strinfos (loc, si, size_zero_node); or more efficiently by just: strinfo si2 = verify_related_strinfos (si); while (si2) { strinfo nsi = si2; si2->dont_invalidate = true; if (si2->next == 0) break; nsi = get_strinfo (si2->next); if (nsi == NULL || nsi->first != si2->first || nsi->prev != si->idx) return; si2 = nsi; } or so - the store in this case shouldn't overwrite a zero byte (otherwise length would be unknown or zero), so it doesn't need to invalidate any of the related cached string lengths. verify_related_strinfos and the extra verification similar to what e.g. adjust_related_strinfos does is there because of the lazy updation, when walking the chains one has to verify some chain element hasn't been invalidated since the chain has been created. *->dont_invalidate is the only kind of store into strinfo structure that is valid even without unshare_strinfo, it is just a hint for the next maybe_invalidate.