https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83448
David Malcolm <dmalcolm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |NEW CC| |msebor at gcc dot gnu.org Assignee|dmalcolm at gcc dot gnu.org |unassigned at gcc dot gnu.org --- Comment #6 from David Malcolm <dmalcolm at gcc dot gnu.org> --- (In reply to David Malcolm from comment #5) > Created attachment 42907 [details] > Work-in-progress patch, with reproducer, and more assertions With the above, the reproducer fails earlier, with the assertions showing where the substring_loc's invariant is first violated. The negative caret_idx is introduced via this code in gimple-ssa-sprintf.c: 2588 /* The size of the destination region is a range. */ 2589 2590 if (target_to_host (*dir.beg) != '%') 2591 { 2592 unsigned HOST_WIDE_INT navail = avail_range.max; 2593 2594 /* For plain character directives (i.e., the format string itself) 2595 but not others, point the caret at the first character that's 2596 past the end of the destination. */ 2597 dirloc.set_caret_index (dirloc.get_caret_idx () + navail); 2598 } (gdb) p dirloc.get_caret_idx () $12 = 3 (gdb) p navail $13 = 2147483647 The substring location code is using "int" for handling the indexes of characters within strings, whereas the above code is using "unsigned HOST_WIDE_INT". I attempted to update the substring location code to use unsigned HOST_WIDE_INT rather than int, but the datatype leaks into libcpp (e.g. the return type of cpp_substring_ranges::get_num_ranges), rather than just gcc... But presumably even if we did use, say 64-bit unsigned ints throughout, this could still overflow (with incorrect albeit non-negative values). Martin: what is the above code attempting to do? It's not clear to me (though this may be -ENOCOFFEE on my part, sorry).