$ /opt/loongson-gnu-5.5/bin/mips64-linux-gnu-gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout x.c
;; Function f (f, funcdef_no=0, decl_uid=1488, cgraph_uid=0, symbol_order=2)
f (int i)
{
<bb 2>:
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1495, cgraph_uid=1, symbol_order=5)
Removing basic block 3
g (int i)
{
unsigned int n;
const char * s;
long unsigned int _4;
<bb 2>:
if (i_2(D) < 0)
goto <bb 4>;
else
goto <bb 3>;
<bb 3>:
<bb 4>:
# s_1 = PHI <&a3(2), &b4(3)>
_4 = __builtin_strlen (s_1);
n_5 = (unsigned int) _4;
if (n_5 > 3)
goto <bb 5>;
else
goto <bb 6>;
<bb 5>:
__builtin_abort ();
<bb 6>:
return;
}
But GCC 8.x works correctly:
$ /opt/mips-gnu-git/bin/mips64-linux-gnu-gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout x.c
;; Function f (f, funcdef_no=0, decl_uid=1584, cgraph_uid=0, symbol_order=2)
f (int i)
{
<bb 2> [local count: 1073741825]:
return;
}
;; Function g (g, funcdef_no=3, decl_uid=1591, cgraph_uid=1, symbol_order=5)
g (int i)
{
<bb 2> [local count: 1073741825]:
return;
}
Testcase:
$ cat x.c
const char a[] = "123";
const char b[] = "1234";
void f (int i)
{
const char *s = i < 0 ? a : b;
unsigned n = __builtin_strlen (s);
if (4 < n)
__builtin_abort ();
}
char a3[3];
char b4[4];
void g (int i)
{
const char *s = i < 0 ? a3 : b4;
unsigned n = __builtin_strlen (s);
if (3 < n)
__builtin_abort ();
}
Martin fixed the bug for GCC 8.x, but after GCC 5.x wi::to_widest was migrated to wi::to_wide, so backport patch failed to build:
../../gcc/wide-int.h: In instantiation of ‘wide_int_storage::wide_int_storage(const T&) [with T = generic_wide_int<wi::extended_tree<192> >]’:
../../gcc/wide-int.h:718:15: required from ‘generic_wide_int<T>::generic_wide_int(const T&) [with T = generic_wide_int<wi::extended_tree<192> >; storage = wide_int_storage]’
../../gcc/tree-ssa-strlen.c:1130:38: required from here
../../gcc/system.h:749:15: error: size of array is negative
typedef int assertion1[(X) ? 1 : -1] ATTRIBUTE_UNUSED
^
../../gcc/wide-int.h:1028:5: note: in expansion of macro ‘STATIC_ASSERT’
{ STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION); }
^~~~~~~~~~~~~
Hi fellows,
As PR78450 mentioned:
But GCC 8.x works correctly:
Testcase:
Martin fixed the bug for GCC 8.x, but after GCC 5.x
wi::to_widest
was migrated towi::to_wide
, so backport patch failed to build:Regards, Leslie Zhai