c: Fold implicit integer-to-floating conversions in static initializers with -froundi...
authorJoseph Myers <joseph@codesourcery.com>
Wed, 3 Nov 2021 14:58:25 +0000 (14:58 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 3 Nov 2021 14:59:22 +0000 (14:59 +0000)
commit600dcd74b8e614c996b492d97878660faf484094
tree8dc7b818bb5a1b08b33fe1c391510e9e93a16cca
parent502ffb1f389011b28ee51815242c7397790802d5
c: Fold implicit integer-to-floating conversions in static initializers with -frounding-math [PR103031]

Recent fixes to avoid inappropriate folding of some conversions to
floating-point types with -frounding-math also prevented such folding
in C static initializers, when folding (in the default rounding mode,
exceptions discarded) is required for correctness.

Folding for static initializers is handled via functions in
fold-const.c calling START_FOLD_INIT and END_FOLD_INIT to adjust flags
such as flag_rounding_math that should not apply in static initializer
context, but no such function was being called for the folding of
these implicit conversions to the type of the object being
initialized, only for explicit conversions as part of the initializer.

Arrange for relevant folding (a fold call in convert, in particular)
to use this special initializer handling (via a new fold_init
function, in particular).

Because convert is used by language-independent code but defined in
each front end, this isn't as simple as just adding a new default
argument to it.  Instead, I added a new convert_init function; that
then gets called by c-family code, and C and C++ need convert_init
implementations (the C++ one does nothing different from convert and
will never actually get called because the new convert_and_check
argument will never be true from C++), but other languages don't.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/
PR c/103031
* fold-const.c (fold_init): New function.
* fold-const.h (fold_init): New prototype.

gcc/c-family/
PR c/103031
* c-common.c (convert_and_check): Add argument init_const.  Call
convert_init if init_const.
* c-common.h (convert_and_check): Update prototype.
(convert_init): New prototype.

gcc/c/
PR c/103031
* c-convert.c (c_convert): New function, based on convert.
(convert): Make into wrapper of c_convert.
(convert_init): New function.
* c-typeck.c (enum impl_conv): Add ic_init_const.
(convert_for_assignment): Handle ic_init_const like ic_init.  Add
new argument to convert_and_check call.
(digest_init): Pass ic_init_const to convert_for_assignment for
initializers required to be constant.

gcc/cp/
PR c/103031
* cvt.c (convert_init): New function.

gcc/testsuite/
PR c/103031
* gcc.dg/init-rounding-math-1.c: New test.
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/c-convert.c
gcc/c/c-typeck.c
gcc/cp/cvt.c
gcc/fold-const.c
gcc/fold-const.h
gcc/testsuite/gcc.dg/init-rounding-math-1.c [new file with mode: 0644]