https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103161

            Bug ID: 103161
           Summary: [12 Regression] Better ranges cause
                    builtin-sprintf-warn-16.c failure
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

On a variety of platforms builtin-sprintf-warn-16.c has started failing since
converting strlen to use Ranger.

Tests that now fail, but worked before (6 tests):

or1k-sim: gcc.dg/tree-ssa/builtin-sprintf-warn-16.c  (test for warnings, line
142)
or1k-sim: gcc.dg/tree-ssa/builtin-sprintf-warn-16.c  (test for warnings, line
243)
or1k-sim: gcc.dg/tree-ssa/builtin-sprintf-warn-16.c (test for excess errors)

The excess errors and line 142 failure are due to getting tighter ranges out of
Ranger which seems to have confused the wrap-around bits in the sprintf
warnings.

A reduced testcase for or1k-elf that you can trigger with a cross:

# 0 "k.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "k.c"






typedef unsigned int size_t;
typedef unsigned int wchar_t;

void sink (void*);
void* get_value (void);
# 22 "k.c"
extern char buf[1];






typedef signed long long sint128_t;
typedef unsigned long long uint128_t;


const sint128_t sint128_max
  = (sint128_t)1 << (sizeof sint128_max * 8 - 2);
const sint128_t uint128_max = (uint128_t)-1;


void test_width_var (void)
{

  {


    extern unsigned w;
    if (w < 5 || (unsigned)-1 - 7 < w)
      w = 5;

    __builtin_sprintf (buf + 1, "%*u", w, *(int*)get_value ()); sink (buf);
  }
}


The relevant bits from the .strlen dump:

Old:
! j.c:52: __builtin_sprintf: objsize = 0, fmtstr = "%*u"
!   Directive 1 at offset 0: "%*u", width in range [0, 2147483648]
!     Result: 1, 1, 2147483648, 2147483648 (1, 1, 2147483648, 2147483648)
    Directive 2 at offset 3: "", length = 1

New:
! k.c:52: __builtin_sprintf: objsize = 0, fmtstr = "%*u"
!   Directive 1 at offset 0: "%*u", width in range [5, 4294967288]
!     Result: 5, 5, -1, 4294967288 (5, 5, -1, -1)
    Directive 2 at offset 3: "", length = 1


AFAICT we've got a tighter range from Ranger, which in turn is confusing some
of the wrap-around logic.

Martin, can you take a look a this?

Reply via email to