expr: Fix up constant_byte_string bitfield handling [PR98366]
authorJakub Jelinek <jakub@redhat.com>
Sat, 19 Dec 2020 21:24:10 +0000 (22:24 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 19 Dec 2020 21:24:10 +0000 (22:24 +0100)
commit69165332a914f1167c3077fa1f57afc64fd8a667
tree39b48d9a3a3ecc7f8913d238dd513dbdbc3a6d1f
parente9e4ddfc5abbf9ee5e657d626264cef89f10b4c3
expr: Fix up constant_byte_string bitfield handling [PR98366]

constant_byte_string now uses a convert_to_bytes function, which doesn't
handle bitfields at all (don't punt on them, just puts them into wrong bits
or bytes).  Furthermore, I don't see a reason why that function should exist
at all, it duplicates native_encode_initializer functionality.
Except that native_encode_initializer punted on flexible array members and 2
tests in the testsuite relied on constant_byte_string handling those.
So, this patch throws away convert_to_bytes, uses native_encode_initializer
instead, but teaches it to handle flexible array members (only in the
non-mask mode with off == -1 for now), furthermore, it adds various corner
case checks that the old implementation was missing (like that STRING_CSTs
use int as length and therefore we shouldn't try to build larger than that
strings, or that native_encode*/native_interpret* APIs require sane
host and target bytes (8-bit on both).

2020-12-19  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/98366
* fold-const.c (native_encode_initializer): Don't try to
memset more than total_bytes with off == -1 even if len is large.
Handle flexible array member initializers if off == -1 and mask is
NULL.
* expr.c (convert_to_bytes): Remove.
(constant_byte_string): Use native_encode_initializer instead of
convert_to_bytes.  Remove extraneous semicolon.  Punt on various
corner-cases the APIs don't handle, like sizes > INT_MAX,
BITS_PER_UNIT != 8, CHAR_BIT != 8.

* gcc.c-torture/execute/pr98366.c: New test.
gcc/expr.c
gcc/fold-const.c
gcc/testsuite/gcc.c-torture/execute/pr98366.c [new file with mode: 0644]