[PATCH] don't trim empty string initializers for pointers (PR 90947)

Martin Sebor msebor@gmail.com
Sun Jun 23 21:51:00 GMT 2019


On 6/22/19 9:37 PM, Jason Merrill wrote:
> On 6/21/19 8:05 PM, Martin Sebor wrote:
>> The solution we implemented in GCC 9 to get the mangling of
>> non-type template arguments of class types containing array
>> members consistent regardless of the form of their
>> initialization introduced a couple of bugs.  One of these
>> is the subject of this patch.  The bug results in stripping
>> trailing initializers for array elements that involve the empty
>> string such as in here:
>>
>>    void f (void)
>>    {
>>      const char* a[1][1] = { "" };
>>      if (!a[0][0])
>>        __builtin_abort ();
>>    }
>>
>> The problem is caused by relying on initializer_zerop() that
>> returns true for the empty string regardless of whether it's
>> used to initialize an array or a pointer (the function doesn't
>> know what the initializer is being used for).
> 
> Why doesn't the existing POINTER_TYPE_P check handle this?  It's clearly 
> intended to.

It does but only only for initializers of "leaf" elements/members.
The function processes initializers of enclosing elements or members
recursively.  When initializer_zerop returns true for one of those,
it doesn't differentiate between an empty string that's being used
to initialize a leaf array or a leaf pointer.

For the example above, the first time through, elt_type is char*
and elt_init is the empty string, or the array char[1], and so
the initializer is retained.

The second time through (after the leaf recursive call returns),
elt_init is { "" } (i.e., an array of one empty string), elt_type
is also an array, and initializer_zerop(elt_init) returns true, so
the initializer is dropped.

I'm actually surprised this initializer_zerop ambiguity between
arrays and strings doesn't come up elsewhere.  That's also why
I added the new function to tree.c.

Btw., it belatedly occurred to me that the new function doesn't
correctly handled unnamed bit-fields so I've corrected it to
handle those as well.  Attached is the revised patch with this
change and a test to exercise it.

Martin

PS I found DECL_UNNAMED_BIT_FIELD in c-family/c-common.h.
I used (DECL_BIT_FIELD (fld) && !DECL_NAME (fld)) because
the former macro isn't available in tree.c.  Does that mean
that that would make the new function not completely correct
in some other languages?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcc-90947.diff
Type: text/x-patch
Size: 21611 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20190623/77b3149a/attachment.bin>


More information about the Gcc-patches mailing list