https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83640
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |ice-on-valid-code Status|NEW |ASSIGNED See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=83642 Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> --- The ICE is caused by the following assertion which expects the offset into the destination of the memory access to be in a range whose lower bound is less than its upper bound: gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1])); The range that is obtained for the test case in comment #4 is that of _9 in the following VRP dump. Its lower bound is 2 (corresponding to the length of string literal) but its upper bound, 9223372036854775808, is equal to PTRDIFF_MIN when interpreted as a signed integer. It's the result of 9223372036854775806 + 2, the sum of the length of the longest string plus that of "*/" (after signed overflow has wrapped it around zero). The upper bound should reflect the longest possible resulting string after the call to memcpy in the dump. Since no object can be larger than PTRDIFF_MAX - 1 bytes, the length of no string can be greater than PTRDIFF_MAX - 2, a more accurate upper bound of the offset is still 9223372036854775806, or still PTRDIFF_MAX - 1. (I opened bug 83642 for this optimization opportunity.) Value ranges after VRP: c_4: VARYING _5: [0, 9223372036854775806] // accurate upper bound of the length of any string _6: VARYING _9: [2, 9223372036854775808] // excessive upper bound _10: VARYING c_11: ~[0B, 0B] EQUIVALENCES: { c_4 } (1 elements) bar (char * b, char * c) { long unsigned int _5; char * _6; long unsigned int _9; char * _10; <bb 2> [local count: 1073741825]: c_4 = foo (); _5 = __builtin_strlen (c_4); _6 = c_4 + _5; __builtin_memcpy (_6, "*/", 2); _9 = _5 + 2; _10 = c_4 + _9; __builtin_strcpy (_10, c_1(D)); return; }