Prevent conversion of character data in array constructors.

Fix for PR fortran/92896 [10 Regression] [DEC] ICE in reduce_unary, at
fortran/arith.c:1283.
    
This was caused by an unintended side affect of "Allow CHARACTER literals
in assignments and data statements" (revision 277975). If the conversion
occurs in a array constructor it is rejected.

From-SVN: r279583
This commit is contained in:
Mark Eggleston 2019-12-19 15:13:25 +00:00 committed by Mark Eggleston
parent aa0e90e7bf
commit 8405874a0e
6 changed files with 48 additions and 6 deletions

View File

@ -1,3 +1,17 @@
2019-12-19 Mark Eggleston <mark.eggleston@codethink.com>
PR fortran/92896
* array.c (walk_array_constructor): Replace call to gfc_convert_type
with call to gfc_convert_type_warn with new argument set to true.
(check_element_type): Replace call to cfg_convert_type with call to
gfc_convert_type_warn with new argument set to true.
* gfortran.h: Add argument "array" to gfc_convert_type_warn default
value set to false.
*intrinsic.c (gfc_convert_type_warn): Update description of arguments.
Add new argument to argument list. Add check for conversion to numeric
or logical from character and array set to true, i.e. if conversion
from character is in an array constructor reject it, goto bad.
2019-12-19 Jakub Jelinek <jakub@redhat.com>
PR fortran/92977

View File

@ -1185,9 +1185,10 @@ walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head)
if (m == MATCH_ERROR)
return m;
}
else if (!gfc_convert_type (e, ts, 1) && e->ts.type != BT_UNKNOWN)
else if (!gfc_convert_type_warn (e, ts, 1, 1, true)
&& e->ts.type != BT_UNKNOWN)
return MATCH_ERROR;
}
}
return MATCH_YES;
}
@ -1386,7 +1387,7 @@ check_element_type (gfc_expr *expr, bool convert)
return 0;
if (convert)
return gfc_convert_type(expr, &constructor_ts, 1) ? 0 : 1;
return gfc_convert_type_warn (expr, &constructor_ts, 1, 1, true) ? 0 : 1;
gfc_error ("Element in %s array constructor at %L is %s",
gfc_typename (&constructor_ts), &expr->where,

View File

@ -3189,7 +3189,8 @@ void gfc_intrinsic_done_1 (void);
char gfc_type_letter (bt, bool logical_equals_int = false);
gfc_symbol * gfc_get_intrinsic_sub_symbol (const char *);
bool gfc_convert_type (gfc_expr *, gfc_typespec *, int);
bool gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int);
bool gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int,
bool array = false);
bool gfc_convert_chartype (gfc_expr *, gfc_typespec *);
int gfc_generic_intrinsic (const char *);
int gfc_specific_intrinsic (const char *);

View File

@ -5096,10 +5096,15 @@ gfc_convert_type (gfc_expr *expr, gfc_typespec *ts, int eflag)
1 Generate a gfc_error()
2 Generate a gfc_internal_error().
'wflag' controls the warning related to conversion. */
'wflag' controls the warning related to conversion.
'array' indicates whether the conversion is in an array constructor.
Non-standard conversion from character to numeric not allowed if true.
*/
bool
gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag,
bool array)
{
gfc_intrinsic_sym *sym;
gfc_typespec from_ts;
@ -5142,6 +5147,12 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
&& gfc_compare_types (&expr->ts, ts))
return true;
/* If array is true then conversion is in an array constructor where
non-standard conversion is not allowed. */
if (array && from_ts.type == BT_CHARACTER
&& (gfc_numeric_ts (ts) || ts->type == BT_LOGICAL))
goto bad;
sym = find_conv (&expr->ts, ts);
if (sym == NULL)
goto bad;

View File

@ -1,3 +1,8 @@
2019-12-19 Mark Eggleston <mark.eggleston@codethink.com>
PR fortran/92896
* gfortran.dg/no_char_conversion_in_array_constructor.f90: New test.
2019-12-19 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/mixed_size_9.c: New test.

View File

@ -0,0 +1,10 @@
! { dg-do compile }
! { dg-options "-fdec-char-conversions" }
program p
print *, -[integer :: 1, [integer(8) :: '2']] ! { dg-error "Cannot convert" }
print *, -[real :: 1, [real(8) :: '2']] ! { dg-error "Cannot convert" }
print *, -[complex :: 1, [complex(8) :: '2']] ! { dg-error "Cannot convert" }
print *, [logical :: 1, [logical(8) :: '2']] ! { dg-error "Cannot convert" }
end