[RFA] varasm: check float size

Message ID 20230602024341.1629656-1-jason@redhat.com
State Committed
Commit e7cc4d703bceb9095316c106eba0d1939c6c8044
Headers
Series [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

Jason Merrill June 2, 2023, 2:43 a.m. UTC
  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

Richard Biener June 2, 2023, 9:29 a.m. UTC | #1
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
>
  

Patch

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