[gcc r14-1498] varasm: check float size
Jason Merrill
jason@gcc.gnu.org
Fri Jun 2 14:09:25 GMT 2023
https://gcc.gnu.org/g:e7cc4d703bceb9095316c106eba0d1939c6c8044
commit r14-1498-ge7cc4d703bceb9095316c106eba0d1939c6c8044
Author: Jason Merrill <jason@redhat.com>
Date: Thu Jun 1 14:41:07 2023 -0400
varasm: check float size
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.
Diff:
---
gcc/varasm.cc | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 571bb2e2f0e..aee1affc57c 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
More information about the Gcc-cvs
mailing list