aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Eggleston <mark.eggleston@codethink.com>2019-12-19 15:13:25 +0000
committerMark Eggleston <markeggleston@gcc.gnu.org>2019-12-19 15:13:25 +0000
commit8405874a0e2db1806332ead2dcf3e9ec563075aa (patch)
tree90a26d11226d612f5fda08c8d2c36feb304072ce
parentaa0e90e7bff935856212b64236cd540acccc66a0 (diff)
downloadgcc-8405874a0e2db1806332ead2dcf3e9ec563075aa.zip
gcc-8405874a0e2db1806332ead2dcf3e9ec563075aa.tar.gz
gcc-8405874a0e2db1806332ead2dcf3e9ec563075aa.tar.bz2
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
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/array.c7
-rw-r--r--gcc/fortran/gfortran.h3
-rw-r--r--gcc/fortran/intrinsic.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/no_char_conversion_in_array_constructor.f9010
6 files changed, 48 insertions, 6 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index b780450..7a71c70 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 1834d2f..bfd4612 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -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,
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3907d14..a266edb 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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 *);
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 76b53bb..c913f5a 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bbca1aa..4e75067 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gfortran.dg/no_char_conversion_in_array_constructor.f90 b/gcc/testsuite/gfortran.dg/no_char_conversion_in_array_constructor.f90
new file mode 100644
index 0000000..7dc4624
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/no_char_conversion_in_array_constructor.f90
@@ -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
+