The attached patch replaces use of %lli and %llu with HOST_WIDE_INT_PRINT_DEC and HOST_WIDE_INT_PRINT_UNSIGNED for portability, and also replaces wide_int::to_shwi() with offset_int::from().
Although I couldn't come up with a test where the latter change above would matter, by using obscenely large offset values I did manage to trigger an assertion in the -Wrestrict pass in place to try to verify the sanity of the offsets/sizes after they have been converted from offset_int to HOST_WIDE_INT for printing (and potentially mangled in the process). I got rid of the assertion since it doesn't serve a useful purpose. Martin
gcc/ChangeLog: * gimple-ssa-warn-restrict.c (builtin_memref::builtin_memref): Use offset_int::from instead of wide_int::to_shwi. (maybe_diag_overlap): Remove assertion. Use HOST_WIDE_INT_PRINT_DEC instead of %lli. * gimple-ssa-sprintf.c (format_directive): Same. (parse_directive): Same. (sprintf_dom_walker::compute_format_length): Same. (try_substitute_return_value): Same. gcc/testsuite/ChangeLog: * gcc.dg/Wrestrict-3.c: New test. Index: /ssd/src/gcc/svn/gcc/testsuite/gcc.dg/Wrestrict-3.c =================================================================== --- /ssd/src/gcc/svn/gcc/testsuite/gcc.dg/Wrestrict-3.c (nonexistent) +++ /ssd/src/gcc/svn/gcc/testsuite/gcc.dg/Wrestrict-3.c (working copy) @@ -0,0 +1,17 @@ +/* Test to verify that the call below with the out-of-bounds offset + doesn't trigger an internal assertion and is diagnosed. + { dg-do compile } + { dg-options "-O2 -Wrestrict" } */ + +#define DIFF_MAX __PTRDIFF_MAX__ + +void test_no_ice (int *d, __PTRDIFF_TYPE__ i, __SIZE_TYPE__ n) +{ + if (i < DIFF_MAX / sizeof *d - 1 || DIFF_MAX / sizeof *d + 2 < i) + i = DIFF_MAX / sizeof *d - 1; + + if (n < DIFF_MAX) + n = DIFF_MAX / sizeof *d; + + __builtin_strncpy ((char*)(d + i), (char*)d, n); /* { dg-warning "\\\[-Wrestrict]" } */ +} Index: gcc/gimple-ssa-warn-restrict.c =================================================================== --- gcc/gimple-ssa-warn-restrict.c (revision 255901) +++ gcc/gimple-ssa-warn-restrict.c (working copy) @@ -276,13 +276,13 @@ builtin_memref::builtin_memref (tree expr, tree si value_range_type rng = get_range_info (offset, &min, &max); if (rng == VR_RANGE) { - offrange[0] = min.to_shwi (); - offrange[1] = max.to_shwi (); + offrange[0] = offset_int::from (min, SIGNED); + offrange[1] = offset_int::from (max, SIGNED); } else if (rng == VR_ANTI_RANGE) { - offrange[0] = (max + 1).to_shwi (); - offrange[1] = (min - 1).to_shwi (); + offrange[0] = offset_int::from (max + 1, SIGNED); + offrange[1] = offset_int::from (min - 1, SIGNED); } else { @@ -1228,24 +1228,30 @@ maybe_diag_overlap (location_t loc, gcall *call, b if (dstref.offrange[0] == dstref.offrange[1] || dstref.offrange[1] > HOST_WIDE_INT_MAX) - sprintf (offstr[0], "%lli", (long long) dstref.offrange[0].to_shwi ()); + sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC, + (long long) dstref.offrange[0].to_shwi ()); else - sprintf (offstr[0], "[%lli, %lli]", + sprintf (offstr[0], + "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", (long long) dstref.offrange[0].to_shwi (), (long long) dstref.offrange[1].to_shwi ()); if (srcref.offrange[0] == srcref.offrange[1] || srcref.offrange[1] > HOST_WIDE_INT_MAX) - sprintf (offstr[1], "%lli", (long long) srcref.offrange[0].to_shwi ()); + sprintf (offstr[1], + HOST_WIDE_INT_PRINT_DEC, + (long long) srcref.offrange[0].to_shwi ()); else - sprintf (offstr[1], "[%lli, %lli]", + sprintf (offstr[1], + "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", (long long) srcref.offrange[0].to_shwi (), (long long) srcref.offrange[1].to_shwi ()); if (ovloff[0] == ovloff[1] || !ovloff[1]) - sprintf (offstr[2], "%lli", (long long) ovloff[0]); + sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, (long long) ovloff[0]); else - sprintf (offstr[2], "[%lli, %lli]", + sprintf (offstr[2], + "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", (long long) ovloff[0], (long long) ovloff[1]); const offset_int maxobjsize = tree_to_shwi (max_object_size ()); @@ -1361,9 +1367,6 @@ maybe_diag_overlap (location_t loc, gcall *call, b } /* Issue "may overlap" diagnostics below. */ - gcc_assert (ovlsiz[0] == 0 - && ovlsiz[1] > 0 - && ovlsiz[1] <= maxobjsize.to_shwi ()); /* Use more concise wording when one of the offsets is unbounded to avoid confusing the user with large and mostly meaningless Index: gcc/gimple-ssa-sprintf.c =================================================================== --- gcc/gimple-ssa-sprintf.c (revision 255901) +++ gcc/gimple-ssa-sprintf.c (working copy) @@ -2993,8 +2993,12 @@ format_directive (const sprintf_dom_walker::call_i if (dump_file && *dir.beg) { - fprintf (dump_file, " Result: %lli, %lli, %lli, %lli " - "(%lli, %lli, %lli, %lli)\n", + fprintf (dump_file, + " Result: " + HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", " + HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC " (" + HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", " + HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ")\n", (long long)fmtres.range.min, (long long)fmtres.range.likely, (long long)fmtres.range.max, @@ -3033,8 +3037,9 @@ parse_directive (sprintf_dom_walker::call_info &in if (dump_file) { - fprintf (dump_file, " Directive %u at offset %llu: \"%.*s\", " - "length = %llu\n", + fprintf (dump_file, " Directive %u at offset " + HOST_WIDE_INT_PRINT_UNSIGNED ": \"%.*s\", " + "length = " HOST_WIDE_INT_PRINT_UNSIGNED "\n", dir.dirno, (unsigned long long)(size_t)(dir.beg - info.fmtstr), (int)dir.len, dir.beg, (unsigned long long)dir.len); @@ -3409,15 +3414,20 @@ parse_directive (sprintf_dom_walker::call_info &in if (dump_file) { - fprintf (dump_file, " Directive %u at offset %llu: \"%.*s\"", + fprintf (dump_file, + " Directive %u at offset " HOST_WIDE_INT_PRINT_UNSIGNED + ": \"%.*s\"", dir.dirno, (unsigned long long)(size_t)(dir.beg - info.fmtstr), (int)dir.len, dir.beg); if (star_width) { if (dir.width[0] == dir.width[1]) - fprintf (dump_file, ", width = %lli", (long long)dir.width[0]); + fprintf (dump_file, ", width = " HOST_WIDE_INT_PRINT_DEC, + (long long)dir.width[0]); else - fprintf (dump_file, ", width in range [%lli, %lli]", + fprintf (dump_file, + ", width in range [" HOST_WIDE_INT_PRINT_DEC + ", " HOST_WIDE_INT_PRINT_DEC "]", (long long)dir.width[0], (long long)dir.width[1]); } @@ -3424,9 +3434,12 @@ parse_directive (sprintf_dom_walker::call_info &in if (star_precision) { if (dir.prec[0] == dir.prec[1]) - fprintf (dump_file, ", precision = %lli", (long long)dir.prec[0]); + fprintf (dump_file, ", precision = " HOST_WIDE_INT_PRINT_DEC, + (long long)dir.prec[0]); else - fprintf (dump_file, ", precision in range [%lli, %lli]", + fprintf (dump_file, + ", precision in range [" HOST_WIDE_INT_PRINT_DEC + HOST_WIDE_INT_PRINT_DEC "]", (long long)dir.prec[0], (long long)dir.prec[1]); } fputc ('\n', dump_file); @@ -3453,7 +3466,9 @@ sprintf_dom_walker::compute_format_length (call_in LOCATION_FILE (callloc), LOCATION_LINE (callloc)); print_generic_expr (dump_file, info.func, dump_flags); - fprintf (dump_file, ": objsize = %llu, fmtstr = \"%s\"\n", + fprintf (dump_file, + ": objsize = " HOST_WIDE_INT_PRINT_UNSIGNED + ", fmtstr = \"%s\"\n", (unsigned long long)info.objsize, info.fmtstr); } @@ -3680,12 +3695,15 @@ try_substitute_return_value (gimple_stmt_iterator const char *what = setrange ? "Setting" : "Discarding"; if (retval[0] != retval[1]) fprintf (dump_file, - " %s %s-bounds return value range [%llu, %llu].\n", + " %s %s-bounds return value range [" + HOST_WIDE_INT_PRINT_UNSIGNED ", " + HOST_WIDE_INT_PRINT_UNSIGNED "].\n", what, inbounds, (unsigned long long)retval[0], (unsigned long long)retval[1]); else - fprintf (dump_file, " %s %s-bounds return value %llu.\n", + fprintf (dump_file, " %s %s-bounds return value " + HOST_WIDE_INT_PRINT_UNSIGNED ".\n", what, inbounds, (unsigned long long)retval[0]); } }