Prevent conversion of character data in array constructors.
authorMark Eggleston <mark.eggleston@codethink.com>
Thu, 19 Dec 2019 15:13:25 +0000 (15:13 +0000)
committerMark Eggleston <markeggleston@gcc.gnu.org>
Thu, 19 Dec 2019 15:13:25 +0000 (15:13 +0000)
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

gcc/fortran/ChangeLog
gcc/fortran/array.c
gcc/fortran/gfortran.h
gcc/fortran/intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/no_char_conversion_in_array_constructor.f90 [new file with mode: 0644]

index b780450a63a5fa23c7ffcc102ab6aef1fc53e275..7a71c70a6e9698f4d930c17f13693693642d68bf 100644 (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
index 1834d2f98a09be200d9dd4dfe903b9e17f00f264..bfd461252d8b490cf2f389e467caf1557b5609ad 100644 (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,
index 3907d1407ac4027b5b6716a504b8a80cc4e46722..a266edb8ed826d0569b61cf124af7c9fb8712643 100644 (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 *);
index 76b53bb7117c2d97ee87a600af76354d7b360274..c913f5ab152fc4f8f73c3e31ce60bcb168f26fd7 100644 (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;
index bbca1aa5b1684b8ba5e8d47a07488171e1b6d84c..4e75067e9ceb843a63ff1a44ee6784aca627ae60 100644 (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.
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 (file)
index 0000000..7dc4624
--- /dev/null
@@ -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
+