Blame SOURCES/0004-Allow-CHARACTER-literals-in-assignments-and-data-sta.patch

d0de29
From c1d6c81730ffda61eff8fccf4d0c7efa3ae6fd8d Mon Sep 17 00:00:00 2001
d0de29
From: Jim MacArthur <jim.macarthur@codethink.co.uk>
d0de29
Date: Thu, 4 Feb 2016 17:18:30 +0000
d0de29
Subject: [PATCH 04/16] Allow CHARACTER literals in assignments and data
d0de29
 statements
d0de29
d0de29
Warnings are raised when this happens.
d0de29
d0de29
Enable using -fdec-char-as-int or -fdec
d0de29
---
d0de29
 gcc/fortran/arith.c                                | 96 +++++++++++++++++++++-
d0de29
 gcc/fortran/arith.h                                |  4 +
d0de29
 gcc/fortran/expr.c                                 |  5 ++
d0de29
 gcc/fortran/intrinsic.c                            | 32 +++++++-
d0de29
 gcc/fortran/lang.opt                               |  5 ++
d0de29
 gcc/fortran/options.c                              |  1 +
d0de29
 gcc/fortran/resolve.c                              | 11 ++-
d0de29
 gcc/fortran/simplify.c                             | 29 ++++++-
d0de29
 gcc/fortran/trans-const.c                          |  3 +-
d0de29
 .../dec_char_conversion_in_assignment_1.f90        | 61 ++++++++++++++
d0de29
 .../dec_char_conversion_in_assignment_2.f90        | 61 ++++++++++++++
d0de29
 .../dec_char_conversion_in_assignment_3.f90        | 61 ++++++++++++++
d0de29
 .../gfortran.dg/dec_char_conversion_in_data_1.f90  | 69 ++++++++++++++++
d0de29
 .../gfortran.dg/dec_char_conversion_in_data_2.f90  | 69 ++++++++++++++++
d0de29
 .../gfortran.dg/dec_char_conversion_in_data_3.f90  | 69 ++++++++++++++++
d0de29
 gcc/testsuite/gfortran.dg/hollerith5.f90           |  5 +-
d0de29
 gcc/testsuite/gfortran.dg/hollerith_legacy.f90     |  2 +-
d0de29
 .../gfortran.dg/no_char_to_int_assign.f90          | 20 +++++
d0de29
 18 files changed, 589 insertions(+), 14 deletions(-)
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
d0de29
 create mode 100644 gcc/testsuite/gfortran.dg/no_char_to_int_assign.f90
d0de29
d0de29
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
d0de29
index f2d311c044c..7e6d6dd3bb8 100644
d0de29
--- a/gcc/fortran/arith.c
d0de29
+++ b/gcc/fortran/arith.c
d0de29
@@ -2553,11 +2553,11 @@ hollerith2representation (gfc_expr *result, gfc_expr *src)
d0de29
   src_len = src->representation.length - src->ts.u.pad;
d0de29
   gfc_target_expr_size (result, &result_len);
d0de29
 
d0de29
-  if (src_len > result_len)
d0de29
+  if (src_len > result_len && warn_character_truncation)
d0de29
     {
d0de29
-      gfc_warning (0,
d0de29
-		   "The Hollerith constant at %L is too long to convert to %qs",
d0de29
-		   &src->where, gfc_typename(&result->ts));
d0de29
+      gfc_warning (OPT_Wcharacter_truncation, "The Hollerith constant at %L "
d0de29
+		   "is truncated in conversion to %qs", &src->where,
d0de29
+		   gfc_typename(&result->ts));
d0de29
     }
d0de29
 
d0de29
   result->representation.string = XCNEWVEC (char, result_len + 1);
d0de29
@@ -2572,6 +2572,36 @@ hollerith2representation (gfc_expr *result, gfc_expr *src)
d0de29
 }
d0de29
 
d0de29
 
d0de29
+/* Helper function to set the representation in a character conversion.
d0de29
+   This assumes that the ts.type and ts.kind of the result have already
d0de29
+   been set.  */
d0de29
+
d0de29
+static void
d0de29
+character2representation (gfc_expr *result, gfc_expr *src)
d0de29
+{
d0de29
+  size_t src_len, result_len;
d0de29
+  int i;
d0de29
+  src_len = src->value.character.length;
d0de29
+  gfc_target_expr_size (result, &result_len);
d0de29
+
d0de29
+  if (src_len > result_len && warn_character_truncation)
d0de29
+    gfc_warning (OPT_Wcharacter_truncation, "The character constant at %L is "
d0de29
+		 "is truncated in conversion to %s", &src->where,
d0de29
+		 gfc_typename(&result->ts));
d0de29
+
d0de29
+  result->representation.string = XCNEWVEC (char, result_len + 1);
d0de29
+
d0de29
+  for (i = 0; i < MIN (result_len, src_len); i++)
d0de29
+    result->representation.string[i] = (char) src->value.character.string[i];
d0de29
+
d0de29
+  if (src_len < result_len)
d0de29
+    memset (&result->representation.string[src_len], ' ',
d0de29
+	    result_len - src_len);
d0de29
+
d0de29
+  result->representation.string[result_len] = '\0'; /* For debugger  */
d0de29
+  result->representation.length = result_len;
d0de29
+}
d0de29
+
d0de29
 /* Convert Hollerith to integer. The constant will be padded or truncated.  */
d0de29
 
d0de29
 gfc_expr *
d0de29
@@ -2587,6 +2617,19 @@ gfc_hollerith2int (gfc_expr *src, int kind)
d0de29
   return result;
d0de29
 }
d0de29
 
d0de29
+/* Convert character to integer. The constant will be padded or truncated. */
d0de29
+
d0de29
+gfc_expr *
d0de29
+gfc_character2int (gfc_expr *src, int kind)
d0de29
+{
d0de29
+  gfc_expr *result;
d0de29
+  result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
d0de29
+
d0de29
+  character2representation (result, src);
d0de29
+  gfc_interpret_integer (kind, (unsigned char *) result->representation.string,
d0de29
+			 result->representation.length, result->value.integer);
d0de29
+  return result;
d0de29
+}
d0de29
 
d0de29
 /* Convert Hollerith to real. The constant will be padded or truncated.  */
d0de29
 
d0de29
@@ -2603,6 +2646,21 @@ gfc_hollerith2real (gfc_expr *src, int kind)
d0de29
   return result;
d0de29
 }
d0de29
 
d0de29
+/* Convert character to real. The constant will be padded or truncated.  */
d0de29
+
d0de29
+gfc_expr *
d0de29
+gfc_character2real (gfc_expr *src, int kind)
d0de29
+{
d0de29
+  gfc_expr *result;
d0de29
+  result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
d0de29
+
d0de29
+  character2representation (result, src);
d0de29
+  gfc_interpret_float (kind, (unsigned char *) result->representation.string,
d0de29
+		       result->representation.length, result->value.real);
d0de29
+
d0de29
+  return result;
d0de29
+}
d0de29
+
d0de29
 
d0de29
 /* Convert Hollerith to complex. The constant will be padded or truncated.  */
d0de29
 
d0de29
@@ -2619,6 +2677,21 @@ gfc_hollerith2complex (gfc_expr *src, int kind)
d0de29
   return result;
d0de29
 }
d0de29
 
d0de29
+/* Convert character to complex. The constant will be padded or truncated.  */
d0de29
+
d0de29
+gfc_expr *
d0de29
+gfc_character2complex (gfc_expr *src, int kind)
d0de29
+{
d0de29
+  gfc_expr *result;
d0de29
+  result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
d0de29
+
d0de29
+  character2representation (result, src);
d0de29
+  gfc_interpret_complex (kind, (unsigned char *) result->representation.string,
d0de29
+			 result->representation.length, result->value.complex);
d0de29
+
d0de29
+  return result;
d0de29
+}
d0de29
+
d0de29
 
d0de29
 /* Convert Hollerith to character.  */
d0de29
 
d0de29
@@ -2654,3 +2727,18 @@ gfc_hollerith2logical (gfc_expr *src, int kind)
d0de29
 
d0de29
   return result;
d0de29
 }
d0de29
+
d0de29
+/* Convert character to logical. The constant will be padded or truncated.  */
d0de29
+
d0de29
+gfc_expr *
d0de29
+gfc_character2logical (gfc_expr *src, int kind)
d0de29
+{
d0de29
+  gfc_expr *result;
d0de29
+  result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where);
d0de29
+
d0de29
+  character2representation (result, src);
d0de29
+  gfc_interpret_logical (kind, (unsigned char *) result->representation.string,
d0de29
+			 result->representation.length, &result->value.logical);
d0de29
+
d0de29
+  return result;
d0de29
+}
d0de29
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
d0de29
index e06c7059885..13ffd8d0b6c 100644
d0de29
--- a/gcc/fortran/arith.h
d0de29
+++ b/gcc/fortran/arith.h
d0de29
@@ -82,7 +82,11 @@ gfc_expr *gfc_hollerith2real (gfc_expr *, int);
d0de29
 gfc_expr *gfc_hollerith2complex (gfc_expr *, int);
d0de29
 gfc_expr *gfc_hollerith2character (gfc_expr *, int);
d0de29
 gfc_expr *gfc_hollerith2logical (gfc_expr *, int);
d0de29
+gfc_expr *gfc_character2int (gfc_expr *, int);
d0de29
+gfc_expr *gfc_character2real (gfc_expr *, int);
d0de29
+gfc_expr *gfc_character2complex (gfc_expr *, int);
d0de29
 gfc_expr *gfc_character2character (gfc_expr *, int);
d0de29
+gfc_expr *gfc_character2logical (gfc_expr *, int);
d0de29
 
d0de29
 #endif /* GFC_ARITH_H  */
d0de29
 
d0de29
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
d0de29
index 474e9ecc401..77600a5f2e8 100644
d0de29
--- a/gcc/fortran/expr.c
d0de29
+++ b/gcc/fortran/expr.c
d0de29
@@ -3695,6 +3695,11 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform,
d0de29
 	  || rvalue->ts.type == BT_HOLLERITH)
d0de29
 	return true;
d0de29
 
d0de29
+      if (flag_dec_char_conversions && (gfc_numeric_ts (&lvalue->ts)
d0de29
+	  || lvalue->ts.type == BT_LOGICAL)     
d0de29
+          && rvalue->ts.type == BT_CHARACTER)
d0de29
+	return true;
d0de29
+
d0de29
       if (lvalue->ts.type == BT_LOGICAL && rvalue->ts.type == BT_LOGICAL)
d0de29
 	return true;
d0de29
 
d0de29
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
d0de29
index c21fbddd5fb..e94d5d3225f 100644
d0de29
--- a/gcc/fortran/intrinsic.c
d0de29
+++ b/gcc/fortran/intrinsic.c
d0de29
@@ -4017,6 +4017,28 @@ add_conversions (void)
d0de29
 	  add_conv (BT_LOGICAL, gfc_logical_kinds[j].kind,
d0de29
 		    BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
d0de29
 	}
d0de29
+
d0de29
+  /* Flang allows character conversions similar to Hollerith conversions
d0de29
+     - the first characters will be turned into ascii values. */
d0de29
+  if (flag_dec_char_conversions)
d0de29
+    {
d0de29
+      /* Character-Integer conversions.  */
d0de29
+      for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
d0de29
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
d0de29
+		  BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
d0de29
+      /* Character-Real conversions.  */
d0de29
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
d0de29
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
d0de29
+		  BT_REAL, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
d0de29
+      /* Character-Complex conversions.  */
d0de29
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
d0de29
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
d0de29
+		  BT_COMPLEX, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
d0de29
+      /* Character-Logical conversions.  */
d0de29
+      for (i = 0; gfc_logical_kinds[i].kind != 0; i++)
d0de29
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
d0de29
+		  BT_LOGICAL, gfc_logical_kinds[i].kind, GFC_STD_LEGACY);
d0de29
+    }
d0de29
 }
d0de29
 
d0de29
 
d0de29
@@ -5128,8 +5150,16 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
d0de29
 			     gfc_typename (&from_ts), gfc_typename (ts),
d0de29
 			     &expr->where);
d0de29
 	}
d0de29
+      else if (flag_dec_char_conversions && from_ts.type == BT_CHARACTER
d0de29
+	       && (gfc_numeric_ts (ts) || ts->type == BT_LOGICAL))
d0de29
+	{
d0de29
+	  if (warn_conversion)
d0de29
+	    gfc_warning_now (OPT_Wconversion, "Conversion from %s to %s at %L",
d0de29
+			     gfc_typename (&from_ts), gfc_typename (ts),
d0de29
+			     &expr->where);
d0de29
+	}
d0de29
       else
d0de29
-        gcc_unreachable ();
d0de29
+	gcc_unreachable ();
d0de29
     }
d0de29
 
d0de29
   /* Insert a pre-resolved function call to the right function.  */
d0de29
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
d0de29
index 13a8e9778bb..5746b99b1d4 100644
d0de29
--- a/gcc/fortran/lang.opt
d0de29
+++ b/gcc/fortran/lang.opt
d0de29
@@ -444,6 +444,11 @@ fdec-duplicates
d0de29
 Fortran Var(flag_dec_duplicates)
d0de29
 Allow varibles to be duplicated in the type specification matches.
d0de29
 
d0de29
+fdec-char-conversions
d0de29
+Fortran Var(flag_dec_char_conversions)
d0de29
+Enable the use of character literals in assignments and data statements
d0de29
+for non-character variables.
d0de29
+
d0de29
 fdec-include
d0de29
 Fortran Var(flag_dec_include)
d0de29
 Enable legacy parsing of INCLUDE as statement.
d0de29
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
d0de29
index f93db8b6d7c..e97b1568810 100644
d0de29
--- a/gcc/fortran/options.c
d0de29
+++ b/gcc/fortran/options.c
d0de29
@@ -76,6 +76,7 @@ set_dec_flags (int value)
d0de29
   SET_BITFLAG (flag_dec_include, value, value);
d0de29
   SET_BITFLAG (flag_dec_format_defaults, value, value);
d0de29
   SET_BITFLAG (flag_dec_duplicates, value, value);
d0de29
+  SET_BITFLAG (flag_dec_char_conversions, value, value);
d0de29
 }
d0de29
 
d0de29
 /* Finalize DEC flags.  */
d0de29
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
d0de29
index 32b8d504ff6..43559185481 100644
d0de29
--- a/gcc/fortran/resolve.c
d0de29
+++ b/gcc/fortran/resolve.c
d0de29
@@ -4320,7 +4320,6 @@ bad_op:
d0de29
   return false;
d0de29
 }
d0de29
 
d0de29
-
d0de29
 /************** Array resolution subroutines **************/
d0de29
 
d0de29
 enum compare_result
d0de29
@@ -10498,6 +10497,16 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
d0de29
   lhs = code->expr1;
d0de29
   rhs = code->expr2;
d0de29
 
d0de29
+  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)
d0de29
+      && rhs->ts.type == BT_CHARACTER
d0de29
+      && rhs->expr_type != EXPR_CONSTANT)
d0de29
+    {
d0de29
+      gfc_error ("Cannot convert CHARACTER into %s at %L",
d0de29
+                 gfc_typename (&lhs->ts),     
d0de29
+                 &rhs->where);
d0de29
+      return false;
d0de29
+    }
d0de29
+
d0de29
   if (rhs->is_boz
d0de29
       && !gfc_notify_std (GFC_STD_GNU, "BOZ literal at %L outside "
d0de29
 			  "a DATA statement and outside INT/REAL/DBLE/CMPLX",
d0de29
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
d0de29
index 6c1f4bd4fce..7d7e3f22f73 100644
d0de29
--- a/gcc/fortran/simplify.c
d0de29
+++ b/gcc/fortran/simplify.c
d0de29
@@ -8457,10 +8457,31 @@ gfc_convert_constant (gfc_expr *e, bt type, int kind)
d0de29
       break;
d0de29
 
d0de29
     case BT_CHARACTER:
d0de29
-      if (type == BT_CHARACTER)
d0de29
-	f = gfc_character2character;
d0de29
-      else
d0de29
-	goto oops;
d0de29
+      switch (type)
d0de29
+	{
d0de29
+	case BT_INTEGER:
d0de29
+	  f = gfc_character2int;
d0de29
+	  break;
d0de29
+
d0de29
+	case BT_REAL:
d0de29
+	  f = gfc_character2real;
d0de29
+	  break;
d0de29
+
d0de29
+	case BT_COMPLEX:
d0de29
+	  f = gfc_character2complex;
d0de29
+	  break;
d0de29
+
d0de29
+	case BT_CHARACTER:
d0de29
+	  f = gfc_character2character;
d0de29
+	  break;
d0de29
+
d0de29
+	case BT_LOGICAL:
d0de29
+	  f = gfc_character2logical;
d0de29
+	  break;
d0de29
+
d0de29
+	default:
d0de29
+	  goto oops;
d0de29
+	}
d0de29
       break;
d0de29
 
d0de29
     default:
d0de29
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
d0de29
index 432d12bf168..b155e35cbdd 100644
d0de29
--- a/gcc/fortran/trans-const.c
d0de29
+++ b/gcc/fortran/trans-const.c
d0de29
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
d0de29
 #include "coretypes.h"
d0de29
 #include "tree.h"
d0de29
 #include "gfortran.h"
d0de29
+#include "options.h"
d0de29
 #include "trans.h"
d0de29
 #include "fold-const.h"
d0de29
 #include "stor-layout.h"
d0de29
@@ -330,7 +331,7 @@ gfc_conv_constant_to_tree (gfc_expr * expr)
d0de29
 			gfc_get_int_type (expr->ts.kind),
d0de29
 			gfc_build_string_const (expr->representation.length,
d0de29
 						expr->representation.string));
d0de29
-	  if (!integer_zerop (tmp) && !integer_onep (tmp))
d0de29
+	  if (!integer_zerop (tmp) && !integer_onep (tmp) && warn_surprising)
d0de29
 	    gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"
d0de29
 			 " has undefined result at %L", &expr->where);
d0de29
 	  return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
d0de29
new file mode 100644
d0de29
index 00000000000..d504f92fbbc
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
d0de29
@@ -0,0 +1,61 @@
d0de29
+! { dg-do run }
d0de29
+! { dg-options "-fdec -Wsurprising -Wcharacter-truncation" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+program test
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  a = '1234'
d0de29
+  b = '1234'
d0de29
+  c = '12341234'
d0de29
+  d = '1234'     ! { dg-warning "undefined result" }
d0de29
+  e = 4h1234
d0de29
+  f = 4h1234
d0de29
+  g = 8h12341234
d0de29
+  h = 4h1234     ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+
d0de29
+  ! padded values
d0de29
+  a = '12'
d0de29
+  b = '12'
d0de29
+  c = '12234'
d0de29
+  d = '124'   ! { dg-warning "undefined result" }
d0de29
+  e = 2h12
d0de29
+  f = 2h12
d0de29
+  g = 5h12234
d0de29
+  h = 3h123   ! { dg-warning "undefined result" }
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+  ! truncated values
d0de29
+  a = '123478'       ! { dg-warning "truncated in" }
d0de29
+  b = '123478'       ! { dg-warning "truncated in" }
d0de29
+  c = '12341234987'  ! { dg-warning "truncated in" }
d0de29
+  d = '1234abc'      ! { dg-warning "truncated in|undefined result" }
d0de29
+  e = 6h123478       ! { dg-warning "truncated in" }
d0de29
+  f = 6h123478       ! { dg-warning "truncated in" }
d0de29
+  g = 11h12341234987 ! { dg-warning "truncated in" }
d0de29
+  h = 7h1234abc      ! { dg-warning "truncated in|undefined result" }
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
d0de29
new file mode 100644
d0de29
index 00000000000..737ddc664de
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
d0de29
@@ -0,0 +1,61 @@
d0de29
+! { dg-do run }
d0de29
+! { dg-options "-fdec-char-conversions -std=legacy -Wcharacter-truncation -Wsurprising" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+program test
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  a = '1234'
d0de29
+  b = '1234'
d0de29
+  c = '12341234'
d0de29
+  d = '1234'     ! { dg-warning "undefined result" }
d0de29
+  e = 4h1234
d0de29
+  f = 4h1234
d0de29
+  g = 8h12341234
d0de29
+  h = 4h1234     ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+
d0de29
+  ! padded values
d0de29
+  a = '12'
d0de29
+  b = '12'
d0de29
+  c = '12234'
d0de29
+  d = '124'   ! { dg-warning "undefined result" }
d0de29
+  e = 2h12
d0de29
+  f = 2h12
d0de29
+  g = 5h12234
d0de29
+  h = 3h123   ! { dg-warning "undefined result" }
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+  ! truncated values
d0de29
+  a = '123478'       ! { dg-warning "truncated in" }
d0de29
+  b = '123478'       ! { dg-warning "truncated in" }
d0de29
+  c = '12341234987'  ! { dg-warning "truncated in" }
d0de29
+  d = '1234abc'      ! { dg-warning "truncated in|undefined result" }
d0de29
+  e = 6h123478       ! { dg-warning "truncated in" }
d0de29
+  f = 6h123478       ! { dg-warning "truncated in" }
d0de29
+  g = 11h12341234987 ! { dg-warning "truncated in" }
d0de29
+  h = 7h1234abc      ! { dg-warning "truncated in|undefined result" }
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
d0de29
new file mode 100644
d0de29
index 00000000000..0ec494c4a92
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
d0de29
@@ -0,0 +1,61 @@
d0de29
+! { dg-do compile }
d0de29
+! { dg-options "-fdec -fno-dec-char-conversions" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+program test
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  a = '1234'     ! { dg-error "Cannot convert" }
d0de29
+  b = '1234'     ! { dg-error "Cannot convert" }
d0de29
+  c = '12341234' ! { dg-error "Cannot convert" }
d0de29
+  d = '1234'     ! { dg-error "Cannot convert" }
d0de29
+  e = 4h1234
d0de29
+  f = 4h1234
d0de29
+  g = 8h12341234
d0de29
+  h = 4h1234
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+
d0de29
+  ! padded values
d0de29
+  a = '12'    ! { dg-error "Cannot convert" }
d0de29
+  b = '12'    ! { dg-error "Cannot convert" }
d0de29
+  c = '12234' ! { dg-error "Cannot convert" }
d0de29
+  d = '124'   ! { dg-error "Cannot convert" }
d0de29
+  e = 2h12
d0de29
+  f = 2h12
d0de29
+  g = 5h12234
d0de29
+  h = 3h123
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+  ! truncated values
d0de29
+  a = '123478'       ! { dg-error "Cannot convert" }
d0de29
+  b = '123478'       ! { dg-error "Cannot convert" }
d0de29
+  c = '12341234987'  ! { dg-error "Cannot convert" }
d0de29
+  d = '1234abc'      ! { dg-error "Cannot convert" }
d0de29
+  e = 6h123478       !
d0de29
+  f = 6h123478       !
d0de29
+  g = 11h12341234987 !
d0de29
+  h = 7h1234abc      !
d0de29
+
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
d0de29
new file mode 100644
d0de29
index 00000000000..c493be9314b
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
d0de29
@@ -0,0 +1,69 @@
d0de29
+! { dg-do run }
d0de29
+! { dg-options "-fdec -Wsurprising" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+
d0de29
+subroutine normal
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-warning "undefined result" }
d0de29
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 / ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine padded
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-warning "undefined result" }
d0de29
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 / ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine truncated
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-warning "too long|undefined result" }
d0de29
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 / ! { dg-warning "too long|undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 9
d0de29
+  if (b.ne.f) stop 10
d0de29
+  if (c.ne.g) stop 11
d0de29
+  if (d.neqv.h) stop 12
d0de29
+end subroutine
d0de29
+
d0de29
+program test
d0de29
+  call normal
d0de29
+  call padded
d0de29
+  call truncated
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
d0de29
new file mode 100644
d0de29
index 00000000000..c7d8e241cec
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
d0de29
@@ -0,0 +1,69 @@
d0de29
+! { dg-do run }
d0de29
+! { dg-options "-fdec-char-conversions -std=legacy -Wsurprising" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+
d0de29
+subroutine normal
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-warning "undefined result" }
d0de29
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 / ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine padded
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-warning "undefined result" }
d0de29
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 / ! { dg-warning "undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine truncated
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-warning "too long|undefined result" }
d0de29
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 / ! { dg-warning "too long|undefined result" }
d0de29
+  
d0de29
+  if (a.ne.e) stop 9
d0de29
+  if (b.ne.f) stop 10
d0de29
+  if (c.ne.g) stop 11
d0de29
+  if (d.neqv.h) stop 12
d0de29
+end subroutine
d0de29
+
d0de29
+program test
d0de29
+  call normal
d0de29
+  call padded
d0de29
+  call truncated
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
d0de29
new file mode 100644
d0de29
index 00000000000..e7d084b5ffc
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
d0de29
@@ -0,0 +1,69 @@
d0de29
+! { dg-do compile }
d0de29
+! { dg-options "-fdec -fno-dec-char-conversions" }
d0de29
+!
d0de29
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+
d0de29
+subroutine normal
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-error "Incompatible types" }
d0de29
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 /
d0de29
+  
d0de29
+  if (a.ne.e) stop 1
d0de29
+  if (b.ne.f) stop 2
d0de29
+  if (c.ne.g) stop 3
d0de29
+  if (d.neqv.h) stop 4
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine padded
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-error "Incompatible types" }
d0de29
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 /
d0de29
+  
d0de29
+  if (a.ne.e) stop 5
d0de29
+  if (b.ne.f) stop 6
d0de29
+  if (c.ne.g) stop 7
d0de29
+  if (d.neqv.h) stop 8
d0de29
+end subroutine
d0de29
+
d0de29
+subroutine truncated
d0de29
+  integer(4) :: a
d0de29
+  real(4) :: b
d0de29
+  complex(4) :: c
d0de29
+  logical(4) :: d
d0de29
+  integer(4) :: e
d0de29
+  real(4) :: f
d0de29
+  complex(4) :: g
d0de29
+  logical(4) :: h
d0de29
+
d0de29
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-error "Incompatible types" }
d0de29
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 /
d0de29
+  
d0de29
+  if (a.ne.e) stop 9
d0de29
+  if (b.ne.f) stop 10
d0de29
+  if (c.ne.g) stop 11
d0de29
+  if (d.neqv.h) stop 12
d0de29
+end subroutine
d0de29
+
d0de29
+program test
d0de29
+  call normal
d0de29
+  call padded
d0de29
+  call truncated
d0de29
+end program
d0de29
+
d0de29
diff --git a/gcc/testsuite/gfortran.dg/hollerith5.f90 b/gcc/testsuite/gfortran.dg/hollerith5.f90
d0de29
index ebd0a117c4f..d17f9ae40cf 100644
d0de29
--- a/gcc/testsuite/gfortran.dg/hollerith5.f90
d0de29
+++ b/gcc/testsuite/gfortran.dg/hollerith5.f90
d0de29
@@ -1,8 +1,9 @@
d0de29
        ! { dg-do compile }
d0de29
+       ! { dg-options "-Wsurprising" }
d0de29
        implicit none
d0de29
        logical b
d0de29
        b = 4Habcd ! { dg-warning "has undefined result" }
d0de29
        end
d0de29
 
d0de29
-! { dg-warning "Hollerith constant" "const" { target *-*-* } 4 }
d0de29
-! { dg-warning "Conversion" "conversion" { target *-*-* } 4 }
d0de29
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 5 }
d0de29
+! { dg-warning "Conversion" "conversion" { target *-*-* } 5 }
d0de29
diff --git a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90 b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
d0de29
index c3322498345..9d7e989b552 100644
d0de29
--- a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
d0de29
+++ b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
d0de29
@@ -1,5 +1,5 @@
d0de29
 ! { dg-do compile }
d0de29
-! { dg-options "-std=legacy" }
d0de29
+! { dg-options "-std=legacy -Wsurprising" }
d0de29
 ! PR15966, PR18781 & PR16531
d0de29
 implicit none
d0de29
 complex(kind=8) x(2) 
d0de29
diff --git a/gcc/testsuite/gfortran.dg/no_char_to_int_assign.f90 b/gcc/testsuite/gfortran.dg/no_char_to_int_assign.f90
d0de29
new file mode 100644
d0de29
index 00000000000..ccfcc9ae512
d0de29
--- /dev/null
d0de29
+++ b/gcc/testsuite/gfortran.dg/no_char_to_int_assign.f90
d0de29
@@ -0,0 +1,20 @@
d0de29
+! { dg-do compile }
d0de29
+! { dg-options "-fdec-char-conversions" }
d0de29
+!
d0de29
+! Test character to int conversion in DATA types
d0de29
+!
d0de29
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
d0de29
+!
d0de29
+program test
d0de29
+  integer a
d0de29
+  real b
d0de29
+  complex c
d0de29
+  logical d
d0de29
+  character e
d0de29
+
d0de29
+  e = "A"
d0de29
+  a = e ! { dg-error "Cannot convert" }
d0de29
+  b = e ! { dg-error "Cannot convert" }
d0de29
+  c = e ! { dg-error "Cannot convert" }
d0de29
+  d = e ! { dg-error "Cannot convert" }
d0de29
+end program
d0de29
-- 
d0de29
2.11.0
d0de29