[PATCH] Avoid infinite loop with duplicate anonymous union fields
Bogdan Harjoc
harjoc@gmail.com
Tue Jul 31 22:03:00 GMT 2018
#define foo(a) did it, thanks!
As Joseph suspected, the hang/no hang result depended on the values of
DECL_NAME pointers:
- with #define foo(a) plus the testcase from bugzilla id 86690 and no
-save-temps, the "return s.a" that triggers lookup_field() will find
the sorted field_array containing:
(gdb) p component
$1 = (tree) 0x7ffff6300050
(gdb) p field_array[0].decl_minimal.name
$0 = (tree) 0x7ffff61cfd70
$1 = (tree) 0x0
$2 = (tree) 0x7ffff63000f0
$3 = (tree) 0x7ffff6300140
$4 = (tree) 0x7ffff6300190
$5 = (tree) 0x7ffff63001e0
$6 = (tree) 0x7ffff6300230
$7 = (tree) 0x7ffff6300280
$8 = (tree) 0x7ffff63002d0
$9 = (tree) 0x7ffff6300320
So array[0] < component < array[2], which loops (I removed the gdb p
commands for field_array[1] and so on).
- with same test-case and with -save-temps I get:
(gdb) p component
$1 = (tree) 0x7ffff6300c30
(gdb) p field_array[0].decl_minimal.name
$0 = (tree) 0x7ffff61cfd70
$1 = (tree) 0x0
$2 = (tree) 0x7ffff6300050
$3 = (tree) 0x7ffff63000a0
$4 = (tree) 0x7ffff63000f0
$5 = (tree) 0x7ffff6300140
$6 = (tree) 0x7ffff6300190
$7 = (tree) 0x7ffff63001e0
$8 = (tree) 0x7ffff6300230
$9 = (tree) 0x7ffff6300280
So component > array[9], and in this case the binary search doesn't
end up with bottom=0 and top=2, where it would hang earlier.
Component here is the s.a field, and with -save-temps, cc1 gets bin.i
as input (which it treats as preprocessed due to the extension)
instead of bin.c. So with preprocessed/unprocessed source, the order
in which builtin/user-defined names are allocated changes, resulting
in a hang or no-hang result.
I propose this testcase for gcc/testsuite/gcc.dg/ as it reproduces
with or without -save-temps, and with no other magic 'scanf'
identifiers because it keeps a0 first in the sorted array and a1
(which will be replaced with NULL) second:
int a0;
struct S
{
int a1;
union {
int a0;
int a1;
int a2, a3, a4, a5, a6, a7, a8, a9;
int a10, a11, a12, a13, a14, a15;
};
};
int f()
{
struct S s;
return s.a0;
}
(gdb) p component
$1 = (tree) 0x7ffff6300c30
(gdb) p field_array[0].decl_minimal.name
$1 = (tree) 0x7ffff6300c30
$1 = (tree) 0x0
$2 = (tree) 0x7ffff6300050
$3 = (tree) 0x7ffff63000a0...
Thanks for the guidance,
Bogdan
On Tue, Jul 31, 2018 at 10:43 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Tue, 31 Jul 2018, Bogdan Harjoc wrote:
>
>> With fresh git sources and contrib/gcc_update the tests pass:
>>
>> === gcc Summary ===
>>
>> # of expected passes 133500
>> # of expected failures 422
>> # of unsupported tests 2104
>>
>> gcc-build/gcc/xgcc version 9.0.0 20180730 (experimental) (GCC)
>>
>> I wasn't able to reduce the input to avoid including <time.h> and as
>> it only reproduces without -save-temps, it's not clear how to write a
>> testcase for this one.
>
> Could you give more details of the paths through the code that are
> involved in the infinite loop, and the different paths you get without
> -save-temps? Is this an issue of dependence on the values of pointers, or
> something like that? Is it possible to produce a test with more instances
> of the problem in it, say, so that the probability of the problem showing
> up at least once with the test is much higher?
>
> A binary search should not result in an infinite loop simply because the
> elements of the array are not sorted; in that case it should just converge
> on an unpredictable element. So more explanation of how the infinite loop
> occurs is needed. (But if choice of an unpredictable element results in
> e.g. subsequent diagnostics varying depending on pointer values, that by
> itself is a problem that may justify avoiding this code in the case where
> the array may not be sorted.)
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
More information about the Gcc-patches
mailing list