[RFA] varasm: check float size
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
pending
|
Test started
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Testing passed
|
Commit Message
Tested x86_64-pc-linux-gnu, OK for trunk?
-- 8< --
In PR95226, the testcase was failing because we tried to output_constant a
NOP_EXPR to float from a double REAL_CST, and so we output a double where
the caller wanted a float. That doesn't happen anymore, but with the
output_constant hunk we will ICE in that situation rather than emit the
wrong number of bytes.
Part of the problem was that initializer_constant_valid_p_1 returned true
for that NOP_EXPR, because it compared the sizes of integer types but not
floating-point types. So the C++ front end assumed it didn't need to fold
the initializer.
PR c++/95226
gcc/ChangeLog:
* varasm.cc (output_constant) [REAL_TYPE]: Check that sizes match.
(initializer_constant_valid_p_1): Compare float precision.
---
gcc/varasm.cc | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
base-commit: 5fccebdbd9666e0adf6dd8357c21d4ef3ac3f83f
Comments
On Fri, Jun 2, 2023 at 4:44 AM Jason Merrill via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Tested x86_64-pc-linux-gnu, OK for trunk?
OK.
> -- 8< --
>
> In PR95226, the testcase was failing because we tried to output_constant a
> NOP_EXPR to float from a double REAL_CST, and so we output a double where
> the caller wanted a float. That doesn't happen anymore, but with the
> output_constant hunk we will ICE in that situation rather than emit the
> wrong number of bytes.
>
> Part of the problem was that initializer_constant_valid_p_1 returned true
> for that NOP_EXPR, because it compared the sizes of integer types but not
> floating-point types. So the C++ front end assumed it didn't need to fold
> the initializer.
>
> PR c++/95226
>
> gcc/ChangeLog:
>
> * varasm.cc (output_constant) [REAL_TYPE]: Check that sizes match.
> (initializer_constant_valid_p_1): Compare float precision.
> ---
> gcc/varasm.cc | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/gcc/varasm.cc b/gcc/varasm.cc
> index 34400ec39ef..dd84754a283 100644
> --- a/gcc/varasm.cc
> +++ b/gcc/varasm.cc
> @@ -4876,16 +4876,16 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
> tree src_type = TREE_TYPE (src);
> tree dest_type = TREE_TYPE (value);
>
> - /* Allow conversions between pointer types, floating-point
> - types, and offset types. */
> + /* Allow conversions between pointer types and offset types. */
> if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
> - || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
> || (TREE_CODE (dest_type) == OFFSET_TYPE
> && TREE_CODE (src_type) == OFFSET_TYPE))
> return initializer_constant_valid_p_1 (src, endtype, cache);
>
> - /* Allow length-preserving conversions between integer types. */
> - if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)
> + /* Allow length-preserving conversions between integer types and
> + floating-point types. */
> + if (((INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
> + || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)))
> && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
> return initializer_constant_valid_p_1 (src, endtype, cache);
>
> @@ -5255,6 +5255,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
> break;
>
> case REAL_TYPE:
> + gcc_assert (size == thissize);
> if (TREE_CODE (exp) != REAL_CST)
> error ("initializer for floating value is not a floating constant");
> else
>
> base-commit: 5fccebdbd9666e0adf6dd8357c21d4ef3ac3f83f
> --
> 2.31.1
>
@@ -4876,16 +4876,16 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
tree src_type = TREE_TYPE (src);
tree dest_type = TREE_TYPE (value);
- /* Allow conversions between pointer types, floating-point
- types, and offset types. */
+ /* Allow conversions between pointer types and offset types. */
if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
- || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
|| (TREE_CODE (dest_type) == OFFSET_TYPE
&& TREE_CODE (src_type) == OFFSET_TYPE))
return initializer_constant_valid_p_1 (src, endtype, cache);
- /* Allow length-preserving conversions between integer types. */
- if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)
+ /* Allow length-preserving conversions between integer types and
+ floating-point types. */
+ if (((INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
+ || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)))
&& (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
return initializer_constant_valid_p_1 (src, endtype, cache);
@@ -5255,6 +5255,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
break;
case REAL_TYPE:
+ gcc_assert (size == thissize);
if (TREE_CODE (exp) != REAL_CST)
error ("initializer for floating value is not a floating constant");
else