[Fortran] Allow CHARACTER literals in assignments and DATA statements - for review

Message ID 6ef3c9e9-0c3c-d860-4589-cb0be4f3333a@codethink.co.uk
State New
Headers show
Series
  • [Fortran] Allow CHARACTER literals in assignments and DATA statements - for review
Related show

Commit Message

Mark Eggleston Oct. 21, 2019, 2:40 p.m.
This is an extension to support a legacy feature supported by other 
compilers such as flang and the sun compiler.  As I understand it this 
feature is associated with DEC so it enabled using 
-fdec-char-conversions and by -fdec.

It allows character literals to be assigned to numeric (INTEGER, REAL, 
COMPLEX) and LOGICAL variables by direct assignment or in DATA statements.

Please find attached the patch which includes changes to the gfortran 
manual.

Tested on x86_64 using "make check-fortran".

Change logs:

gcc/fortran/ChangeLog

     Jim MacArthur  <jim.macarthur@codethink.co.uk>
     Mark Eggleston  <mark.eggleston@codethink.com>

     * arith.c (hollerith2representation): Use OPT_Wcharacter_truncation in
     call to gfc_warning.  Add character2representation, gfc_character2int,
     gfc_character2real, gfc_character2complex and gfc_character2logical.
     * arith.h: Add prototypes for gfc_character2int, gfc_character2real,
     gfc_character2complex and gfc_character2logical.
     * expr.c (gfc_check_assign): Return true if left hand side is numeric
     or logical and the right hand side is character.
     * gfortran.texi: Add -fdec-char-conversions.
     * intrinsic.c (add_convdersions): Add conversions from character to
     integer, real, complex and logical types for their supported kinds.
     * invoke.texi: Add option to list of options.
     * invoke.texi: Add Character conversion subsection to Extensions
     section.
     * lang.opt: Add new option.
     * options.c (set_dec_flags): Add SET_BITFLAG for
     flag_dec_char_conversions.
     * resolve.c (resolve_ordindary_assign): Issue error if the left hand
     side is numeric or logical and the right hand side is a character
     variable.
     * simplify.c (gfc_convert_constant): Assign the conversion function
     depending on destination type.
     * trans-const.c (gfc_constant_to_tree): Use OPT_Wsurprising in
     gfc_warning allowing the warning to be switched off.

gcc/testsuite/ChangeLog

     Jim MacArthur <jim.macarthur@codethink.co.uk>
     Mark Eggleston <mark.eggleston@codethink.com>

     PR fortran/89103
     * gfortran.dg/dec_char_conversion_in_assignment_1.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_2.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_3.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_1.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_2.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_3.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_4.f90: New test.
     * gfortran.dg/hollerith5.f90: Add -Wsurprising to options.
     * gfortran.dg/hollerith_legacy.f90: Add -Wsurprising to options.
     * gfortran.dg/no_char_to_numeric_assign.f90: New test.

-- 
https://www.codethink.co.uk/privacy.html

Comments

Steve Kargl Oct. 21, 2019, 4:23 p.m. | #1
On Mon, Oct 21, 2019 at 03:40:27PM +0100, Mark Eggleston wrote:
> This is an extension to support a legacy feature supported by other 

> compilers such as flang and the sun compiler.  As I understand it this 

> feature is associated with DEC so it enabled using 

> -fdec-char-conversions and by -fdec.

> 


Without this patch, the following code

% cat a.f90
  integer(4) a
  a = '1234'
  print *, a
  end

produces an error

% gfcx -c a.f90
a.f90:2:6:

    2 |   a = '1234'
      |      1
Error: Cannot convert CHARACTER(4) to INTEGER(4) at (1)

With the new option or -fdec, I would hope/expect ar
warning would be issued, which can only be suppressed
by -w, e.g., 

% gfcx -c -fdec a.f90
a.f90:2:6:

    2 |   a = '1234'
      |      1
Warning: Nonstandard conversion of CHARACTER(4) to INTEGER(4) at (1)

This hopefully will encourage people to fix their codes.

-- 
Steve
Tobias Burnus Oct. 25, 2019, 8:03 a.m. | #2
Hello Mark, hi all,

On 10/21/19 4:40 PM, Mark Eggleston wrote:
> This is an extension to support a legacy feature supported by other 

> compilers such as flang and the sun compiler.  As I understand it this 

> feature is associated with DEC so it enabled using 

> -fdec-char-conversions and by -fdec.

>

> It allows character literals to be assigned to numeric (INTEGER, REAL, 

> COMPLEX) and LOGICAL variables by direct assignment or in DATA 

> statements.


>     * arith.c (hollerith2representation): Use 

> OPT_Wcharacter_truncation in

>     call to gfc_warning.


This has two effects: First, it permits to toggle the warning on and 
off; secondly, it disables the warning by default. It is enabled by 
-Wall, however. – I think that's acceptable: while Holleriths are less 
transparent as normal strings, for normal strings the result is identical.


> +  result->representation.string[result_len] = '\0'; /* For debugger  */


Tiny nit: full stop after 'debugger'.


> +/* Convert character to integer. The constant will be padded or truncated. */


And here an extra space before '*/'.


> +Allowing character literals to be used in a similar way to Hollerith constants

> +is a non-standard extension.

> +

> +Character literals can be used in @code{DATA} statements and assignments with


I wonder whether one should mention here explicitly that only 
default-kind (i.e. kind=1) character strings are permitted. 
Additionally, I wonder whether -fdec-char-conversion should be mentioned 
here – without, it is not supported and the error message doesn't point 
to this option.


> +

> +  /* Flang allows character conversions similar to Hollerith conversions

> +     - the first characters will be turned into ascii values. */


Is this Flang or DEC or …? I thought we talk about legacy support and 
Flang is not really legacy.


> --- a/gcc/fortran/resolve.c

> +++ b/gcc/fortran/resolve.c

>   

> +  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)

> +      && rhs->ts.type == BT_CHARACTER

> +      && rhs->expr_type != EXPR_CONSTANT)

> +    {

> +      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),

> +		 gfc_typename (lhs), &rhs->where);

> +      return false;

> +    }


Maybe add a comment like:
/* Happens with flag_dec_char_conversions for nonconstant strings.  */
might help casual readers to understand where this if comes from.


> @@ -331,8 +332,9 @@ gfc_conv_constant_to_tree (gfc_expr * expr)

>   			gfc_build_string_const (expr->representation.length,

>   						expr->representation.string));

>   	  if (!integer_zerop (tmp) && !integer_onep (tmp))

> -	    gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"

> -			 " has undefined result at %L", &expr->where);

> +	    gfc_warning (OPT_Wsurprising, "Assigning value other than 0 or 1 "

> +		         "to LOGICAL has undefined result at %L",

> +			 &expr->where);


I am not happy with this. We had odd issues with combining code 
generated by gfortran and ifort and Booleans types ("logical"). Namely, 
gfortran uses 0 and 1 – while ifort uses -1 and 0. When using ".not. 
var", it is sufficient to flip a single bit – either the first or the 
last bit – and it is sufficient to look only a single bit.

Hence, one can get ".not. var .eqv. var".

The same result one can get when assigning "-1" to logical. Hence, a 
default warning makes more sense than -Wsurprising. At least, 
-Wsurprising is enabled by default.

Hence, I wonder whether your 'OPT_Wsurprising' or 
'flag_dec_char_conversions ? OPT_Wsurprising : 0' makes more sense.


Actually, I don't quickly see whether   4_'string'  (i.e. kind=4) 
strings are rejected or not. The gfc_character2* functions all assume 
kind=1 characters – while code like gfc_convert_constant or the 
resolve.c code only looks at BT_CHARACTER.
On the other hand, the add_conv calls in intrintrinsic.c's 
add_conversions are only added for the default-character kind.

In any case, can you add a test which checks that – even with 
-fdec-char-conversion – assigning a 2_'string' and 4_'string' to a 
integer/real/complex/logical will be rejected at compile time?

Otherwise, it looks okay to me.

Tobias
Mark Eggleston Nov. 5, 2019, 9:55 a.m. | #3
On 25/10/2019 09:03, Tobias Burnus wrote:
> Hello Mark, hi all,

>

> On 10/21/19 4:40 PM, Mark Eggleston wrote:

>> This is an extension to support a legacy feature supported by other 

>> compilers such as flang and the sun compiler.  As I understand it 

>> this feature is associated with DEC so it enabled using 

>> -fdec-char-conversions and by -fdec.

>>

>> It allows character literals to be assigned to numeric (INTEGER, 

>> REAL, COMPLEX) and LOGICAL variables by direct assignment or in DATA 

>> statements.

>

>>     * arith.c (hollerith2representation): Use 

>> OPT_Wcharacter_truncation in

>>     call to gfc_warning.

>

> This has two effects: First, it permits to toggle the warning on and 

> off; secondly, it disables the warning by default. It is enabled by 

> -Wall, however. – I think that's acceptable: while Holleriths are less 

> transparent as normal strings, for normal strings the result is 

> identical.

>

>

>> + result->representation.string[result_len] = '\0'; /* For debugger  */

>

> Tiny nit: full stop after 'debugger'.

Done.
>

>

>> +/* Convert character to integer. The constant will be padded or 

>> truncated. */

>

> And here an extra space before '*/'.

Done.
>

>

>> +Allowing character literals to be used in a similar way to Hollerith 

>> constants

>> +is a non-standard extension.

>> +

>> +Character literals can be used in @code{DATA} statements and 

>> assignments with

>

> I wonder whether one should mention here explicitly that only 

> default-kind (i.e. kind=1) character strings are permitted. 

> Additionally, I wonder whether -fdec-char-conversion should be 

> mentioned here – without, it is not supported and the error message 

> doesn't point to this option.

>

Now mentions -fdec-char-conversion and kind=1.
>

>> +

>> +  /* Flang allows character conversions similar to Hollerith 

>> conversions

>> +     - the first characters will be turned into ascii values. */

>

> Is this Flang or DEC or …? I thought we talk about legacy support and 

> Flang is not really legacy.

>

>

Re-worded.
>> --- a/gcc/fortran/resolve.c

>> +++ b/gcc/fortran/resolve.c

>>   +  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)

>> +      && rhs->ts.type == BT_CHARACTER

>> +      && rhs->expr_type != EXPR_CONSTANT)

>> +    {

>> +      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),

>> +         gfc_typename (lhs), &rhs->where);

>> +      return false;

>> +    }

>

> Maybe add a comment like:

> /* Happens with flag_dec_char_conversions for nonconstant strings.  */

> might help casual readers to understand where this if comes from.

>

Done.
>

>> @@ -331,8 +332,9 @@ gfc_conv_constant_to_tree (gfc_expr * expr)

>>               gfc_build_string_const (expr->representation.length,

>>                           expr->representation.string));

>>         if (!integer_zerop (tmp) && !integer_onep (tmp))

>> -        gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"

>> -             " has undefined result at %L", &expr->where);

>> +        gfc_warning (OPT_Wsurprising, "Assigning value other than 0 

>> or 1 "

>> +                 "to LOGICAL has undefined result at %L",

>> +             &expr->where);

>

> I am not happy with this. We had odd issues with combining code 

> generated by gfortran and ifort and Booleans types ("logical"). 

> Namely, gfortran uses 0 and 1 – while ifort uses -1 and 0. When using 

> ".not. var", it is sufficient to flip a single bit – either the first 

> or the last bit – and it is sufficient to look only a single bit.

>

> Hence, one can get ".not. var .eqv. var".

>

> The same result one can get when assigning "-1" to logical. Hence, a 

> default warning makes more sense than -Wsurprising. At least, 

> -Wsurprising is enabled by default.

>

> Hence, I wonder whether your 'OPT_Wsurprising' or 

> 'flag_dec_char_conversions ? OPT_Wsurprising : 0' makes more sense.

>

The latter.
>

> Actually, I don't quickly see whether   4_'string'  (i.e. kind=4) 

> strings are rejected or not. The gfc_character2* functions all assume 

> kind=1 characters – while code like gfc_convert_constant or the 

> resolve.c code only looks at BT_CHARACTER.

> On the other hand, the add_conv calls in intrintrinsic.c's 

> add_conversions are only added for the default-character kind.

>

> In any case, can you add a test which checks that – even with 

> -fdec-char-conversion – assigning a 2_'string' and 4_'string' to a 

> integer/real/complex/logical will be rejected at compile time?

>

Did not add 2_'string' tests as 2 is not accepted as a valid kind for 
characters. The addition of 4_'string' in a data statement resulted in 
an ICE which has been fixed by only accepting characters of kind=1.
> Otherwise, it looks okay to me.

>

> Tobias

>

>

I noticed that warning were not produced for conversion to logicals, 
re-ordering of an if..else if sequence fixes that problem. Additional 
test cases have been added.

Steve Kargl suggested a revision to the conversion warning adding 
"Nonstandard" to the text this has also been done.

Tested on x86_64 using make -j 8 check-fortran.

Please find attached the updated patch, the change logs follow. OK to 
commit?

regards,

Mark

gcc/fortran/ChangeLog

     Jim MacArthur  <jim.macarthur@codethink.co.uk>
     Mark Eggleston  <mark.eggleston@codethink.com>

     * arith.c (hollerith2representation): Use OPT_Wcharacter_truncation in
     call to gfc_warning.  Add character2representation, gfc_character2int,
     gfc_character2real, gfc_character2complex and gfc_character2logical.
     * arith.h: Add prototypes for gfc_character2int, gfc_character2real,
     gfc_character2complex and gfc_character2logical.
     * expr.c (gfc_check_assign): Return true if left hand side is numeric
     or logical and the right hand side is character and of kind=1.
     * gfortran.texi: Add -fdec-char-conversions.
     * intrinsic.c (add_conversions): Add conversions from character to
     integer, real, complex and logical types for their supported kinds.
     (gfc_convert_type_warn): Reorder if..else if.. sequence so that 
warnings
     are produced for conversion to logical.
     * invoke.texi: Add option to list of options.
     * invoke.texi: Add Character conversion subsection to Extensions
     section.
     * lang.opt: Add new option.
     * options.c (set_dec_flags): Add SET_BITFLAG for
     flag_dec_char_conversions.
     * resolve.c (resolve_ordindary_assign): Issue error if the left hand
     side is numeric or logical and the right hand side is a character
     variable.
     * simplify.c (gfc_convert_constant): Assign the conversion function
     depending on destination type.
     * trans-const.c (gfc_constant_to_tree): Use OPT_Wsurprising in
     gfc_warning allowing the warning to be switched off only if
     flag_dec_char_conversions is enabled.

gcc/testsuite/gfortran.dg

     Jim MacArthur <jim.macarthur@codethink.co.uk>
     Mark Eggleston <mark.eggleston@codethink.com>

     PR fortran/89103
     * gfortran.dg/dec_char_conversion_in_assignment_1.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_2.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_3.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_4.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_5.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_6.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_7.f90: New test.
     * gfortran.dg/dec_char_conversion_in_assignment_8.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_1.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_2.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_3.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_4.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_5.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_6.f90: New test.
     * gfortran.dg/dec_char_conversion_in_data_7.f90: New test.
     * gfortran.dg/hollerith5.f90: Add -Wsurprising to options.
     * gfortran.dg/hollerith_legacy.f90: Add -Wsurprising to options.
     * gfortran.dg/no_char_to_numeric_assign.f90: New test.

-- 
https://www.codethink.co.uk/privacy.html
From acb37e3563d4b8fcd51ad1754683e8004cb7a1e7 Mon Sep 17 00:00:00 2001
From: Jim MacArthur <jim.macarthur@codethink.co.uk>

Date: Thu, 4 Feb 2016 17:18:30 +0000
Subject: [PATCH] Allow CHARACTER literals in assignments and data statements

Warnings are raised when this happens.

Enable using -fdec-char-as-int or -fdec
---
 gcc/fortran/arith.c                                | 96 +++++++++++++++++++++-
 gcc/fortran/arith.h                                |  4 +
 gcc/fortran/expr.c                                 |  6 ++
 gcc/fortran/gfortran.texi                          | 25 ++++++
 gcc/fortran/intrinsic.c                            | 66 +++++++++++----
 gcc/fortran/invoke.texi                            | 17 ++--
 gcc/fortran/lang.opt                               |  5 ++
 gcc/fortran/options.c                              |  1 +
 gcc/fortran/resolve.c                              | 12 +++
 gcc/fortran/simplify.c                             | 29 ++++++-
 gcc/fortran/trans-const.c                          |  6 +-
 .../dec_char_conversion_in_assignment_1.f90        | 61 ++++++++++++++
 .../dec_char_conversion_in_assignment_2.f90        | 31 +++++++
 .../dec_char_conversion_in_assignment_3.f90        | 44 ++++++++++
 .../dec_char_conversion_in_assignment_4.f90        | 20 +++++
 .../dec_char_conversion_in_assignment_5.f90        | 16 ++++
 .../dec_char_conversion_in_assignment_6.f90        | 14 ++++
 .../dec_char_conversion_in_assignment_7.f90        | 30 +++++++
 .../dec_char_conversion_in_assignment_8.f90        | 17 ++++
 .../gfortran.dg/dec_char_conversion_in_data_1.f90  | 87 ++++++++++++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_2.f90  | 45 ++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_3.f90  | 20 +++++
 .../gfortran.dg/dec_char_conversion_in_data_4.f90  | 17 ++++
 .../gfortran.dg/dec_char_conversion_in_data_5.f90  | 15 ++++
 .../gfortran.dg/dec_char_conversion_in_data_6.f90  | 33 ++++++++
 .../gfortran.dg/dec_char_conversion_in_data_7.f90  | 17 ++++
 gcc/testsuite/gfortran.dg/hollerith5.f90           |  5 +-
 gcc/testsuite/gfortran.dg/hollerith_legacy.f90     |  2 +-
 .../gfortran.dg/no_char_to_numeric_assign.f90      | 21 +++++
 29 files changed, 726 insertions(+), 36 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_6.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_8.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_6.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90

diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index ff279db4992..10b3e5c103f 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -2510,9 +2510,9 @@ hollerith2representation (gfc_expr *result, gfc_expr *src)
 
   if (src_len > result_len)
     {
-      gfc_warning (0,
-		   "The Hollerith constant at %L is too long to convert to %qs",
-		   &src->where, gfc_typename(&result->ts));
+      gfc_warning (OPT_Wcharacter_truncation, "The Hollerith constant at %L "
+		   "is truncated in conversion to %qs", &src->where,
+		   gfc_typename(&result->ts));
     }
 
   result->representation.string = XCNEWVEC (char, result_len + 1);
@@ -2527,6 +2527,36 @@ hollerith2representation (gfc_expr *result, gfc_expr *src)
 }
 
 
+/* Helper function to set the representation in a character conversion.
+   This assumes that the ts.type and ts.kind of the result have already
+   been set.  */
+
+static void
+character2representation (gfc_expr *result, gfc_expr *src)
+{
+  size_t src_len, result_len;
+  int i;
+  src_len = src->value.character.length;
+  gfc_target_expr_size (result, &result_len);
+
+  if (src_len > result_len)
+    gfc_warning (OPT_Wcharacter_truncation, "The character constant at %L is "
+		 "truncated in conversion to %s", &src->where,
+		 gfc_typename(&result->ts));
+
+  result->representation.string = XCNEWVEC (char, result_len + 1);
+
+  for (i = 0; i < MIN (result_len, src_len); i++)
+    result->representation.string[i] = (char) src->value.character.string[i];
+
+  if (src_len < result_len)
+    memset (&result->representation.string[src_len], ' ',
+	    result_len - src_len);
+
+  result->representation.string[result_len] = '\0'; /* For debugger.  */
+  result->representation.length = result_len;
+}
+
 /* Convert Hollerith to integer. The constant will be padded or truncated.  */
 
 gfc_expr *
@@ -2542,8 +2572,21 @@ gfc_hollerith2int (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to integer.  The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2int (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_integer (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, result->value.integer);
+  return result;
+}
 
-/* Convert Hollerith to real. The constant will be padded or truncated.  */
+/* Convert Hollerith to real.  The constant will be padded or truncated.  */
 
 gfc_expr *
 gfc_hollerith2real (gfc_expr *src, int kind)
@@ -2558,6 +2601,21 @@ gfc_hollerith2real (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to real.  The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2real (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_float (kind, (unsigned char *) result->representation.string,
+		       result->representation.length, result->value.real);
+
+  return result;
+}
+
 
 /* Convert Hollerith to complex. The constant will be padded or truncated.  */
 
@@ -2574,6 +2632,21 @@ gfc_hollerith2complex (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to complex. The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2complex (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_complex (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, result->value.complex);
+
+  return result;
+}
+
 
 /* Convert Hollerith to character.  */
 
@@ -2609,3 +2682,18 @@ gfc_hollerith2logical (gfc_expr *src, int kind)
 
   return result;
 }
+
+/* Convert character to logical. The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2logical (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_logical (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, &result->value.logical);
+
+  return result;
+}
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index 39366caaba1..85c8b8cef41 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -77,7 +77,11 @@ gfc_expr *gfc_hollerith2real (gfc_expr *, int);
 gfc_expr *gfc_hollerith2complex (gfc_expr *, int);
 gfc_expr *gfc_hollerith2character (gfc_expr *, int);
 gfc_expr *gfc_hollerith2logical (gfc_expr *, int);
+gfc_expr *gfc_character2int (gfc_expr *, int);
+gfc_expr *gfc_character2real (gfc_expr *, int);
+gfc_expr *gfc_character2complex (gfc_expr *, int);
 gfc_expr *gfc_character2character (gfc_expr *, int);
+gfc_expr *gfc_character2logical (gfc_expr *, int);
 
 #endif /* GFC_ARITH_H  */
 
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index c508890d68d..9e3c8c42297 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3722,6 +3722,12 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform,
 	  || rvalue->ts.type == BT_HOLLERITH)
 	return true;
 
+      if (flag_dec_char_conversions && (gfc_numeric_ts (&lvalue->ts)
+	  || lvalue->ts.type == BT_LOGICAL)
+	  && rvalue->ts.type == BT_CHARACTER
+	  && rvalue->ts.kind == gfc_default_character_kind)
+	return true;
+
       if (lvalue->ts.type == BT_LOGICAL && rvalue->ts.type == BT_LOGICAL)
 	return true;
 
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 02d30e19660..a34ac5aa1bf 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -1600,6 +1600,7 @@ additional compatibility extensions along with those enabled by
 * Unary operators::
 * Implicitly convert LOGICAL and INTEGER values::
 * Hollerith constants support::
+* Character conversion::
 * Cray pointers::
 * CONVERT specifier::
 * OpenMP::
@@ -1955,6 +1956,30 @@ obtained by using the @code{TRANSFER} statement, as in this example.
 @end smallexample
 
 
+@node Character conversion
+@subsection Character conversion
+@cindex conversion, to character
+
+Allowing character literals to be used in a similar way to Hollerith constants
+is a non-standard extension.  This feature is enabled using
+-fdec-char-conversions and only applies to character literals of @code{kind=1}.
+
+Character literals can be used in @code{DATA} statements and assignments with
+numeric (@code{INTEGER}, @code{REAL}, or @code{COMPLEX}) or @code{LOGICAL}
+variables. Like Hollerith constants they are copied byte-wise fashion. The
+constant will be padded with spaces or truncated to fit the size of the
+variable in which it is stored.
+
+Examples:
+@smallexample
+      integer*4 x
+      data x / 'abcd' /
+
+      x = 'A'       ! Will be padded.
+      x = 'ab1234'  ! Will be truncated.
+@end smallexample
+
+
 @node Cray pointers
 @subsection Cray pointers
 @cindex pointer, Cray
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index ac5af10a775..572967f5d4e 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -4025,6 +4025,29 @@ add_conversions (void)
 	  add_conv (BT_LOGICAL, gfc_logical_kinds[j].kind,
 		    BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
 	}
+
+  /* DEC legacy feature allows character conversions similar to Hollerith
+     conversions - the character data will transferred on a byte by byte
+     basis.  */
+  if (flag_dec_char_conversions)
+    {
+      /* Character-Integer conversions.  */
+      for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Real conversions.  */
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_REAL, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Complex conversions.  */
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_COMPLEX, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Logical conversions.  */
+      for (i = 0; gfc_logical_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_LOGICAL, gfc_logical_kinds[i].kind, GFC_STD_LEGACY);
+    }
 }
 
 
@@ -5119,8 +5142,10 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
   /* At this point, a conversion is necessary. A warning may be needed.  */
   if ((gfc_option.warn_std & sym->standard) != 0)
     {
+      const char *type_name = is_char_constant ? gfc_typename (expr)
+					       : gfc_typename (&from_ts);
       gfc_warning_now (0, "Extension: Conversion from %s to %s at %L",
-		       gfc_typename (&from_ts), gfc_dummy_typename (ts),
+		       type_name, gfc_dummy_typename (ts),
 		       &expr->where);
     }
   else if (wflag)
@@ -5135,14 +5160,14 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 	     If range checking was disabled, but -Wconversion enabled,
 	     a non range checked warning is generated below.  */
 	}
-      else if (from_ts.type == BT_LOGICAL || ts->type == BT_LOGICAL)
+      else if (flag_dec_char_conversions && from_ts.type == BT_CHARACTER
+	       && (gfc_numeric_ts (ts) || ts->type == BT_LOGICAL))
 	{
-	  /* Do nothing. This block exists only to simplify the other
-	     else-if expressions.
-	       LOGICAL <> LOGICAL    no warning, independent of kind values
-	       LOGICAL <> INTEGER    extension, warned elsewhere
-	       LOGICAL <> REAL       invalid, error generated elsewhere
-	       LOGICAL <> COMPLEX    invalid, error generated elsewhere  */
+	  const char *type_name = is_char_constant ? gfc_typename (expr)
+						   : gfc_typename (&from_ts);
+	  gfc_warning_now (OPT_Wconversion, "Nonstandard conversion from %s "
+			   "to %s at %L", type_name, gfc_typename (ts),
+			   &expr->where);
 	}
       else if (from_ts.type == ts->type
 	       || (from_ts.type == BT_INTEGER && ts->type == BT_REAL)
@@ -5159,7 +5184,7 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 				 "conversion from %s to %s at %L",
 				 gfc_typename (&from_ts), gfc_typename (ts),
 				 &expr->where);
-	      else if (warn_conversion_extra)
+	      else
 		gfc_warning_now (OPT_Wconversion_extra, "Conversion from %s to %s "
 				 "at %L", gfc_typename (&from_ts),
 				 gfc_typename (ts), &expr->where);
@@ -5171,7 +5196,7 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 	{
 	  /* Conversion from REAL/COMPLEX to INTEGER or COMPLEX to REAL
 	     usually comes with a loss of information, regardless of kinds.  */
-	  if (warn_conversion && expr->expr_type != EXPR_CONSTANT)
+	  if (expr->expr_type != EXPR_CONSTANT)
 	    gfc_warning_now (OPT_Wconversion, "Possible change of value in "
 			     "conversion from %s to %s at %L",
 			     gfc_typename (&from_ts), gfc_typename (ts),
@@ -5180,13 +5205,21 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
       else if (from_ts.type == BT_HOLLERITH || ts->type == BT_HOLLERITH)
 	{
 	  /* If HOLLERITH is involved, all bets are off.  */
-	  if (warn_conversion)
-	    gfc_warning_now (OPT_Wconversion, "Conversion from %s to %s at %L",
-			     gfc_typename (&from_ts), gfc_dummy_typename (ts),
-			     &expr->where);
+	  gfc_warning_now (OPT_Wconversion, "Conversion from %s to %s at %L",
+			   gfc_typename (&from_ts), gfc_dummy_typename (ts),
+			   &expr->where);
+	}
+      else if (from_ts.type == BT_LOGICAL || ts->type == BT_LOGICAL)
+	{
+	  /* Do nothing. This block exists only to simplify the other
+	     else-if expressions.
+	       LOGICAL <> LOGICAL    no warning, independent of kind values
+	       LOGICAL <> INTEGER    extension, warned elsewhere
+	       LOGICAL <> REAL       invalid, error generated elsewhere
+	       LOGICAL <> COMPLEX    invalid, error generated elsewhere  */
 	}
       else
-        gcc_unreachable ();
+	gcc_unreachable ();
     }
 
   /* Insert a pre-resolved function call to the right function.  */
@@ -5244,8 +5277,7 @@ bad:
     }
 
   gfc_internal_error ("Cannot convert %qs to %qs at %L", type_name,
-		      gfc_typename (ts),
-		      &expr->where);
+		      gfc_typename (ts), &expr->where);
   /* Not reached */
 }
 
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 1d5cec12302..46ee3c9241b 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -118,9 +118,9 @@ by type.  Explanations are in the following sections.
 @xref{Fortran Dialect Options,,Options controlling Fortran dialect}.
 @gccoptlist{-fall-intrinsics -fallow-argument-mismatch -fallow-invalid-boz @gol
 -fbackslash -fcray-pointer -fd-lines-as-code -fd-lines-as-comments -fdec @gol
--fdec-structure-fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol
--fdec-format-defaults -fdec-blank-format-item -fdefault-double-8 @gol
--fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 @gol
+-fdec-char-conversions -fdec-structure -fdec-intrinsic-ints -fdec-static @gol
+-fdec-math -fdec-include -fdec-format-defaults -fdec-blank-format-item @gol
+-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 @gol
 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -fpad-source -ffree-form @gol
 -ffree-line-length-@var{n} -ffree-line-length-none -fimplicit-none @gol
@@ -273,14 +273,19 @@ For details on GNU Fortran's implementation of these extensions see the
 full documentation.
 
 Other flags enabled by this switch are:
-@option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-structure}
-@option{-fdec-intrinsic-ints} @option{-fdec-static} @option{-fdec-math}
-@option{-fdec-include} @option{-fdec-blank-format-item}
+@option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-char-conversions}
+@option{-fdec-structure} @option{-fdec-intrinsic-ints} @option{-fdec-static}
+@option{-fdec-math} @option{-fdec-include} @option{-fdec-blank-format-item}
 @option{-fdec-format-defaults}
 
 If @option{-fd-lines-as-code}/@option{-fd-lines-as-comments} are unset, then
 @option{-fdec} also sets @option{-fd-lines-as-comments}.
 
+@item -fdec-char-conversions
+@opindex @code{fdec-char-conversions}
+Enable the use of character literals in assignments and data statements
+for non-character variables.
+
 @item -fdec-structure
 @opindex @code{fdec-structure}
 Enable DEC @code{STRUCTURE} and @code{RECORD} as well as @code{UNION},
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 35b1206a2c2..5fcd1ff9075 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -460,6 +460,11 @@ fdec-blank-format-item
 Fortran Var(flag_dec_blank_format_item)
 Enable the use of blank format items in format strings.
 
+fdec-char-conversions
+Fortran Var(flag_dec_char_conversions)
+Enable the use of character literals in assignments and data statements
+for non-character variables.
+
 fdec-include
 Fortran Var(flag_dec_include)
 Enable legacy parsing of INCLUDE as statement.
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index c875ec1b55f..305c57de85d 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -76,6 +76,7 @@ set_dec_flags (int value)
   SET_BITFLAG (flag_dec_include, value, value);
   SET_BITFLAG (flag_dec_format_defaults, value, value);
   SET_BITFLAG (flag_dec_blank_format_item, value, value);
+  SET_BITFLAG (flag_dec_char_conversions, value, value);
 }
 
 /* Finalize DEC flags.  */
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 218c2edba57..a39b9549d7e 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -10689,6 +10689,18 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
   lhs = code->expr1;
   rhs = code->expr2;
 
+  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)
+      && rhs->ts.type == BT_CHARACTER
+      && rhs->expr_type != EXPR_CONSTANT)
+    {
+      /* Use of -fdec-char-conversions allows assignment of character data
+	 to non-character variables.  This not permited for nonconstant
+	 strings.  */
+      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),
+		 gfc_typename (lhs), &rhs->where);
+      return false;
+    }
+
   /* Handle the case of a BOZ literal on the RHS.  */
   if (rhs->ts.type == BT_BOZ)
     {
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index fa5aefe20c6..2eb1943c3ee 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -8522,10 +8522,31 @@ gfc_convert_constant (gfc_expr *e, bt type, int kind)
       break;
 
     case BT_CHARACTER:
-      if (type == BT_CHARACTER)
-	f = gfc_character2character;
-      else
-	goto oops;
+      switch (type)
+	{
+	case BT_INTEGER:
+	  f = gfc_character2int;
+	  break;
+
+	case BT_REAL:
+	  f = gfc_character2real;
+	  break;
+
+	case BT_COMPLEX:
+	  f = gfc_character2complex;
+	  break;
+
+	case BT_CHARACTER:
+	  f = gfc_character2character;
+	  break;
+
+	case BT_LOGICAL:
+	  f = gfc_character2logical;
+	  break;
+
+	default:
+	  goto oops;
+	}
       break;
 
     default:
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
index 432d12bf168..7ce02639373 100644
--- a/gcc/fortran/trans-const.c
+++ b/gcc/fortran/trans-const.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tree.h"
 #include "gfortran.h"
+#include "options.h"
 #include "trans.h"
 #include "fold-const.h"
 #include "stor-layout.h"
@@ -331,8 +332,9 @@ gfc_conv_constant_to_tree (gfc_expr * expr)
 			gfc_build_string_const (expr->representation.length,
 						expr->representation.string));
 	  if (!integer_zerop (tmp) && !integer_onep (tmp))
-	    gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"
-			 " has undefined result at %L", &expr->where);
+	    gfc_warning (flag_dec_char_conversions ? OPT_Wsurprising : 0,
+			 "Assigning value other than 0 or 1 to LOGICAL has "
+			 "undefined result at %L", &expr->where);
 	  return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
 	}
       else
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
new file mode 100644
index 00000000000..9dc2ece1efd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
@@ -0,0 +1,61 @@
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  a = '1234'
+  b = '1234'
+  c = '12341234'
+  d = '1234'
+  e = 4h1234
+  f = 4h1234
+  g = 8h12341234
+  h = 4h1234
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+
+  ! padded values
+  a = '12'
+  b = '12'
+  c = '12234'
+  d = '124'
+  e = 2h12
+  f = 2h12
+  g = 5h12234
+  h = 3h123
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+  ! truncated values
+  a = '123478'
+  b = '123478'
+  c = '12341234987'
+  d = '1234abc'
+  e = 6h123478
+  f = 6h123478
+  g = 11h12341234987
+  h = 7h1234abc
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+end program
+
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
new file mode 100644
index 00000000000..ffa71dc4126
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+! { dg-options "-fdec -Wconversion" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_assignment_1.f90"
+
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 16 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 17 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 18 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 19 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 20 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 21 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 22 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 23 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 31 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 32 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 33 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 34 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 35 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 36 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 37 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 38 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 46 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 47 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 48 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 49 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 50 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 51 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 52 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 53 }
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
new file mode 100644
index 00000000000..7df55153b8a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+! { dg-options "-fdec-char-conversions" }
+!
+! Contributeds by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_assignment_1.f90"
+
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 16 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 17 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 18 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 19 }
+! { dg-warning "Extension: Hollerith constant" " " { target *-*-* } 20 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 21 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 22 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 23 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 20 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 21 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 22 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 23 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 31 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 32 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 33 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 34 }
+! { dg-warning "Extension: Hollerith constant" " " { target *-*-* } 35 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 36 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 37 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 38 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 35 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 36 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 37 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 38 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 46 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 47 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 48 }
+! { dg-warning "Extension: Conversion from CHARACTER" " " { target *-*-* } 49 }
+! { dg-warning "Extension: Hollerith constant" " " { target *-*-* } 50 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 51 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 52 }
+! { dg-warning "Extension: Hollerith constant"  " " { target *-*-* } 53 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 50 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 51 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 52 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 53 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90
new file mode 100644
index 00000000000..6de97395f81
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fdec -fno-dec-char-conversions" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_assignment_1.f90"
+
+! { dg-error "Cannot convert" " " { target *-*-* } 16 }
+! { dg-error "Cannot convert" " " { target *-*-* } 17 }
+! { dg-error "Cannot convert" " " { target *-*-* } 18 }
+! { dg-error "Cannot convert" " " { target *-*-* } 19 }
+! { dg-error "Cannot convert" " " { target *-*-* } 31 }
+! { dg-error "Cannot convert" " " { target *-*-* } 32 }
+! { dg-error "Cannot convert" " " { target *-*-* } 33 }
+! { dg-error "Cannot convert" " " { target *-*-* } 34 }
+! { dg-error "Cannot convert" " " { target *-*-* } 46 }
+! { dg-error "Cannot convert" " " { target *-*-* } 47 }
+! { dg-error "Cannot convert" " " { target *-*-* } 48 }
+! { dg-error "Cannot convert" " " { target *-*-* } 49 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_5.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_5.f90
new file mode 100644
index 00000000000..9bad441f42a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_5.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fdec -Wcharacter-truncation" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_assignment_1.f90"
+
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 46 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 47 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 48 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 49 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 50 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 51 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 52 }
+! { dg-warning "is truncated in conversion" " " { target *-*-* } 53 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_6.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_6.f90
new file mode 100644
index 00000000000..5eebec46a44
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_6.f90
@@ -0,0 +1,14 @@
+! { dg-do run }
+! { dg-options "-fdec -Wsurprising" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_assignment_1.f90"
+
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 19 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 23 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 34 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 38 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 49 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 53 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_7.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_7.f90
new file mode 100644
index 00000000000..07d6f747865
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_7.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+! { dg-options "-fdec -Wconversion -Wcharacter-truncation" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4), parameter :: a = '1234'
+  real(4), parameter :: b = '12'
+  complex(4), parameter :: c = '12341234'
+  logical(4), parameter :: d = 'abcd'
+  integer(4), parameter :: e = 4h1234
+  real(4), parameter :: f = 2h12
+  complex(4), parameter :: g = 8h12341234
+  logical(4), parameter :: h = 4habcd
+
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+end program
+
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 7 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 8 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 9 }
+! { dg-warning "Nonstandard conversion from CHARACTER" " " { target *-*-* } 10 }
+! { dg-warning "Conversion from HOLLERITH to INTEGER" " " { target *-*-* } 11 }
+! { dg-warning "Conversion from HOLLERITH to REAL" " " { target *-*-* } 12 }
+! { dg-warning "Conversion from HOLLERITH to COMPLEX" " " { target *-*-* } 13 }
+! { dg-warning "Conversion from HOLLERITH to LOGICAL" " " { target *-*-* } 14 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_8.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_8.f90
new file mode 100644
index 00000000000..3520cd1b5d9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_8.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+
+  a = 4_'1234'     ! { dg-error "Cannot convert CHARACTER\\(4,4\\) to" }
+  b = 4_'12'       ! { dg-error "Cannot convert CHARACTER\\(2,4\\) to" }
+  c = 4_'12341234' ! { dg-error "Cannot convert CHARACTER\\(8,4\\) to" }
+  d = 4_'abcd'     ! { dg-error "Cannot convert CHARACTER\\(4,4\\) to" }
+end program
+
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
new file mode 100644
index 00000000000..1bd354b4b1e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
@@ -0,0 +1,87 @@
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+subroutine normal
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a / '1234' /
+  data b / '1234' /
+  data c / '12341234' / ! double the length for complex
+  data d / '1234' / 
+  data e / 4h1234 /
+  data f / 4h1234 /
+  data g / 8h12341234 / ! double the length for complex
+  data h / 4h1234 /
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+end subroutine
+
+subroutine padded
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a / '12' /
+  data b / '12' /
+  data c / '12334' /
+  data d / '123' /
+  data e / 2h12 /
+  data f / 2h12 /
+  data g / 5h12334 /
+  data h / 3h123 /
+  
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+end subroutine
+
+subroutine truncated
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a / '123478' /
+  data b / '123478' /
+  data c / '1234123498' /
+  data d / '12345' /
+  data e / 6h123478 /
+  data f / 6h123478 /
+  data g / 10h1234123498 /
+  data h / 5h12345 /
+  
+  if (a.ne.e) stop 9
+  if (b.ne.f) stop 10
+  if (c.ne.g) stop 11
+  if (d.neqv.h) stop 12
+end subroutine
+
+program test
+  call normal
+  call padded
+  call truncated
+end program
+
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
new file mode 100644
index 00000000000..5c6f39cca01
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+! { dg-options "-fdec-char-conversions" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_data_1.f90"
+
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 21 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 22 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 23 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 24 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 46 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 47 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 48 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 49 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 71 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 72 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 73 }
+! { dg-warning "Legacy Extension: Hollerith constant" " " { target *-*-* } 74 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 21 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 22 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 23 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 24 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 46 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 47 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 48 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 49 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 71 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 72 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 73 }
+! { dg-warning "Extension: Conversion from HOLLERITH" " " { target *-*-* } 74 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(4\\)" " " { target *-*-* } 17 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(4\\)" " " { target *-*-* } 18 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(8\\)" " " { target *-*-* } 19 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(4\\)" " " { target *-*-* } 20 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(2\\)" " " { target *-*-* } 42 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(2\\)" " " { target *-*-* } 43 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(5\\)" " " { target *-*-* } 44 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(3\\)" " " { target *-*-* } 45 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(6\\)" " " { target *-*-* } 67 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(6\\)" " " { target *-*-* } 68 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(10\\)" " " { target *-*-* } 69 }
+! { dg-warning "Extension: Conversion from CHARACTER\\(5\\)" " " { target *-*-* } 70 }
+
+
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
new file mode 100644
index 00000000000..0d6dce186b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fdec -fno-dec-char-conversions" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_data_1.f90"
+
+! { dg-error "Incompatible types" " " { target *-*-* } 17 }
+! { dg-error "Incompatible types" " " { target *-*-* } 18 }
+! { dg-error "Incompatible types" " " { target *-*-* } 19 }
+! { dg-error "Incompatible types" " " { target *-*-* } 20 }
+! { dg-error "Incompatible types" " " { target *-*-* } 42 }
+! { dg-error "Incompatible types" " " { target *-*-* } 43 }
+! { dg-error "Incompatible types" " " { target *-*-* } 44 }
+! { dg-error "Incompatible types" " " { target *-*-* } 45 }
+! { dg-error "Incompatible types" " " { target *-*-* } 67 }
+! { dg-error "Incompatible types" " " { target *-*-* } 68 }
+! { dg-error "Incompatible types" " " { target *-*-* } 69 }
+! { dg-error "Incompatible types" " " { target *-*-* } 70 }
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
new file mode 100644
index 00000000000..c25fe067556
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+! { dg-options "-fdec -Wcharacter-truncation" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_data_1.f90"
+
+! { dg-warning "character constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 67 }
+! { dg-warning "character constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 68 }
+! { dg-warning "character constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 69 }
+! { dg-warning "character constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 70 }
+! { dg-warning "Hollerith constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 71 }
+! { dg-warning "Hollerith constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 72 }
+! { dg-warning "Hollerith constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 73 }
+! { dg-warning "Hollerith constant at \\(1\\) is truncated in conversion" " " { target *-*-* } 74 }
+
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_5.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_5.f90
new file mode 100644
index 00000000000..08d3c58f006
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_5.f90
@@ -0,0 +1,15 @@
+! { dg-do run }
+! { dg-options "-fdec -Wsurprising" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_data_1.f90"
+
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 20 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 24 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 45 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 49 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 70 }
+! { dg-warning "Assigning value other than 0 or 1 to LOGICAL" " " { target *-*-* } 74 }
+
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_6.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_6.f90
new file mode 100644
index 00000000000..10fa7c11c02
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_6.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+! { dg-options "-fdec -Wconversion" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+include "dec_char_conversion_in_data_1.f90"
+
+! { dg-warning "Nonstandard conversion from CHARACTER\\(4\\)" " " { target *-*-* } 17 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(4\\)" " " { target *-*-* } 18 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(8\\)" " " { target *-*-* } 19 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(4\\)" " " { target *-*-* } 20 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 21 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 22 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 23 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 24 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(2\\)" " " { target *-*-* } 42 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(2\\)" " " { target *-*-* } 43 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(5\\)" " " { target *-*-* } 44 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(3\\)" " " { target *-*-* } 45 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 46 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 47 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 48 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 49 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(6\\)" " " { target *-*-* } 67 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(6\\)" " " { target *-*-* } 68 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(10\\)" " " { target *-*-* } 69 }
+! { dg-warning "Nonstandard conversion from CHARACTER\\(5\\)" " " { target *-*-* } 70 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 71 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 72 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 73 }
+! { dg-warning "Conversion from HOLLERITH" " " { target *-*-* } 74 }
+
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_7.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_7.f90
new file mode 100644
index 00000000000..64b6b4fbf44
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_7.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+
+  data a / 4_'1234' /     ! { dg-error "attempted conversion of CHARACTER\\(4,4\\)" }
+  data b / 4_'12'   /     ! { dg-error "attempted conversion of CHARACTER\\(2,4\\)" }
+  data c / 4_'12341234' / ! { dg-error "attempted conversion of CHARACTER\\(8,4\\)" }
+  data d / 4_'abcd' /     ! { dg-error "attempted conversion of CHARACTER\\(4,4\\)" }
+end program
+
diff --git a/gcc/testsuite/gfortran.dg/hollerith5.f90 b/gcc/testsuite/gfortran.dg/hollerith5.f90
index ebd0a117c4f..d17f9ae40cf 100644
--- a/gcc/testsuite/gfortran.dg/hollerith5.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith5.f90
@@ -1,8 +1,9 @@
        ! { dg-do compile }
+       ! { dg-options "-Wsurprising" }
        implicit none
        logical b
        b = 4Habcd ! { dg-warning "has undefined result" }
        end
 
-! { dg-warning "Hollerith constant" "const" { target *-*-* } 4 }
-! { dg-warning "Conversion" "conversion" { target *-*-* } 4 }
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 5 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 5 }
diff --git a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90 b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
index c3322498345..9d7e989b552 100644
--- a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-std=legacy" }
+! { dg-options "-std=legacy -Wsurprising" }
 ! PR15966, PR18781 & PR16531
 implicit none
 complex(kind=8) x(2) 
diff --git a/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90 b/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90
new file mode 100644
index 00000000000..3c60403160a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fdec-char-conversions" }
+!
+! Test character variables can not be assigned to numeric and
+! logical variables.
+!
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer a
+  real b
+  complex c
+  logical d
+  character e
+
+  e = "A"
+  a = e ! { dg-error "Cannot convert" }
+  b = e ! { dg-error "Cannot convert" }
+  c = e ! { dg-error "Cannot convert" }
+  d = e ! { dg-error "Cannot convert" }
+end program
-- 
2.11.0
Mark Eggleston Nov. 8, 2019, 9:45 a.m. | #4
PING - OK, to commit? I have a pending patch that needs this in place.

On 05/11/2019 09:55, Mark Eggleston wrote:
>

> On 25/10/2019 09:03, Tobias Burnus wrote:

>> Hello Mark, hi all,

>>

>> On 10/21/19 4:40 PM, Mark Eggleston wrote:

>>> This is an extension to support a legacy feature supported by other 

>>> compilers such as flang and the sun compiler.  As I understand it 

>>> this feature is associated with DEC so it enabled using 

>>> -fdec-char-conversions and by -fdec.

>>>

>>> It allows character literals to be assigned to numeric (INTEGER, 

>>> REAL, COMPLEX) and LOGICAL variables by direct assignment or in DATA 

>>> statements.

>>

>>>     * arith.c (hollerith2representation): Use 

>>> OPT_Wcharacter_truncation in

>>>     call to gfc_warning.

>>

>> This has two effects: First, it permits to toggle the warning on and 

>> off; secondly, it disables the warning by default. It is enabled by 

>> -Wall, however. – I think that's acceptable: while Holleriths are 

>> less transparent as normal strings, for normal strings the result is 

>> identical.

>>

>>

>>> + result->representation.string[result_len] = '\0'; /* For debugger  */

>>

>> Tiny nit: full stop after 'debugger'.

> Done.

>>

>>

>>> +/* Convert character to integer. The constant will be padded or 

>>> truncated. */

>>

>> And here an extra space before '*/'.

> Done.

>>

>>

>>> +Allowing character literals to be used in a similar way to 

>>> Hollerith constants

>>> +is a non-standard extension.

>>> +

>>> +Character literals can be used in @code{DATA} statements and 

>>> assignments with

>>

>> I wonder whether one should mention here explicitly that only 

>> default-kind (i.e. kind=1) character strings are permitted. 

>> Additionally, I wonder whether -fdec-char-conversion should be 

>> mentioned here – without, it is not supported and the error message 

>> doesn't point to this option.

>>

> Now mentions -fdec-char-conversion and kind=1.

>>

>>> +

>>> +  /* Flang allows character conversions similar to Hollerith 

>>> conversions

>>> +     - the first characters will be turned into ascii values. */

>>

>> Is this Flang or DEC or …? I thought we talk about legacy support and 

>> Flang is not really legacy.

>>

>>

> Re-worded.

>>> --- a/gcc/fortran/resolve.c

>>> +++ b/gcc/fortran/resolve.c

>>>   +  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)

>>> +      && rhs->ts.type == BT_CHARACTER

>>> +      && rhs->expr_type != EXPR_CONSTANT)

>>> +    {

>>> +      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),

>>> +         gfc_typename (lhs), &rhs->where);

>>> +      return false;

>>> +    }

>>

>> Maybe add a comment like:

>> /* Happens with flag_dec_char_conversions for nonconstant strings.  */

>> might help casual readers to understand where this if comes from.

>>

> Done.

>>

>>> @@ -331,8 +332,9 @@ gfc_conv_constant_to_tree (gfc_expr * expr)

>>>               gfc_build_string_const (expr->representation.length,

>>>                           expr->representation.string));

>>>         if (!integer_zerop (tmp) && !integer_onep (tmp))

>>> -        gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"

>>> -             " has undefined result at %L", &expr->where);

>>> +        gfc_warning (OPT_Wsurprising, "Assigning value other than 0 

>>> or 1 "

>>> +                 "to LOGICAL has undefined result at %L",

>>> +             &expr->where);

>>

>> I am not happy with this. We had odd issues with combining code 

>> generated by gfortran and ifort and Booleans types ("logical"). 

>> Namely, gfortran uses 0 and 1 – while ifort uses -1 and 0. When using 

>> ".not. var", it is sufficient to flip a single bit – either the first 

>> or the last bit – and it is sufficient to look only a single bit.

>>

>> Hence, one can get ".not. var .eqv. var".

>>

>> The same result one can get when assigning "-1" to logical. Hence, a 

>> default warning makes more sense than -Wsurprising. At least, 

>> -Wsurprising is enabled by default.

>>

>> Hence, I wonder whether your 'OPT_Wsurprising' or 

>> 'flag_dec_char_conversions ? OPT_Wsurprising : 0' makes more sense.

>>

> The latter.

>>

>> Actually, I don't quickly see whether   4_'string'  (i.e. kind=4) 

>> strings are rejected or not. The gfc_character2* functions all assume 

>> kind=1 characters – while code like gfc_convert_constant or the 

>> resolve.c code only looks at BT_CHARACTER.

>> On the other hand, the add_conv calls in intrintrinsic.c's 

>> add_conversions are only added for the default-character kind.

>>

>> In any case, can you add a test which checks that – even with 

>> -fdec-char-conversion – assigning a 2_'string' and 4_'string' to a 

>> integer/real/complex/logical will be rejected at compile time?

>>

> Did not add 2_'string' tests as 2 is not accepted as a valid kind for 

> characters. The addition of 4_'string' in a data statement resulted in 

> an ICE which has been fixed by only accepting characters of kind=1.

>> Otherwise, it looks okay to me.

>>

>> Tobias

>>

>>

> I noticed that warning were not produced for conversion to logicals, 

> re-ordering of an if..else if sequence fixes that problem. Additional 

> test cases have been added.

>

> Steve Kargl suggested a revision to the conversion warning adding 

> "Nonstandard" to the text this has also been done.

>

> Tested on x86_64 using make -j 8 check-fortran.

>

> Please find attached the updated patch, the change logs follow. OK to 

> commit?

>

> regards,

>

> Mark

>

> gcc/fortran/ChangeLog

>

>     Jim MacArthur  <jim.macarthur@codethink.co.uk>

>     Mark Eggleston  <mark.eggleston@codethink.com>

>

>     * arith.c (hollerith2representation): Use 

> OPT_Wcharacter_truncation in

>     call to gfc_warning.  Add character2representation, 

> gfc_character2int,

>     gfc_character2real, gfc_character2complex and gfc_character2logical.

>     * arith.h: Add prototypes for gfc_character2int, gfc_character2real,

>     gfc_character2complex and gfc_character2logical.

>     * expr.c (gfc_check_assign): Return true if left hand side is numeric

>     or logical and the right hand side is character and of kind=1.

>     * gfortran.texi: Add -fdec-char-conversions.

>     * intrinsic.c (add_conversions): Add conversions from character to

>     integer, real, complex and logical types for their supported kinds.

>     (gfc_convert_type_warn): Reorder if..else if.. sequence so that 

> warnings

>     are produced for conversion to logical.

>     * invoke.texi: Add option to list of options.

>     * invoke.texi: Add Character conversion subsection to Extensions

>     section.

>     * lang.opt: Add new option.

>     * options.c (set_dec_flags): Add SET_BITFLAG for

>     flag_dec_char_conversions.

>     * resolve.c (resolve_ordindary_assign): Issue error if the left hand

>     side is numeric or logical and the right hand side is a character

>     variable.

>     * simplify.c (gfc_convert_constant): Assign the conversion function

>     depending on destination type.

>     * trans-const.c (gfc_constant_to_tree): Use OPT_Wsurprising in

>     gfc_warning allowing the warning to be switched off only if

>     flag_dec_char_conversions is enabled.

>

> gcc/testsuite/gfortran.dg

>

>     Jim MacArthur <jim.macarthur@codethink.co.uk>

>     Mark Eggleston <mark.eggleston@codethink.com>

>

>     PR fortran/89103

>     * gfortran.dg/dec_char_conversion_in_assignment_1.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_2.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_3.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_4.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_5.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_6.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_7.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_8.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_1.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_2.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_3.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_4.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_5.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_6.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_7.f90: New test.

>     * gfortran.dg/hollerith5.f90: Add -Wsurprising to options.

>     * gfortran.dg/hollerith_legacy.f90: Add -Wsurprising to options.

>     * gfortran.dg/no_char_to_numeric_assign.f90: New test.

>

-- 
https://www.codethink.co.uk/privacy.html
Tobias Burnus Nov. 8, 2019, 10:17 a.m. | #5
On 11/8/19 10:45 AM, Mark Eggleston wrote:
> PING - OK, to commit? I have a pending patch that needs this in place. 

Thanks for the ping. — Any chance, that you also work on some of the 
general issues once in a while (cf. Bugzilla remark below); e.g. one bug 
per week or fortnight? (Can be a simple one, just not to keep the number 
of bugs growing.)

@Anyone – side question: Are there other pending patches? Ignoring one 
OpenMP and several OpenACC patches, I am currently aware of:
* [Needs review] José's PR92142 - CFI_setpointer corrupts descriptor 
patch [FSF copyright assignment exists]
* [Nearly ready, but needs fixes/follow-up patch] Steve's PR91178 for 
code like 'call foo(a, (a))'
* [Approved but not committed] Paul's PR92123 patch for bind(C) + alloc 
scalars.

Side remark: On the bind(C) side, I think PR 92189 should be fixed. 
Additionally, there are several recent reports on segfaults and 
regressions, looking Bugzilla (component = fortran, sort by change data).


Back to this pending patch:

On 11/5/19 10:55 AM, Mark Eggleston wrote:
> I noticed that warning were not produced for conversion to logicals, 

> re-ordering of an if..else if sequence fixes that problem. Additional 

> test cases have been added.

Looks as if reviewing and revisiting the patch was worthwhile :-) Thanks!

> Please find attached the updated patch, the change logs follow. OK to 

> commit?


LGTM. Thanks for patch.

Cheers,

Tobias

PS: I still find it interesting, which Fortran code gets used; from a 
supercomputing centre, I heard that everything between 
afterwards-never-touched FORTRAN IV code to code using the latest 
Fortran features is used. (But most amazing I find code, which gets 
newly written in a FORTRAN 66 style/features with some sparse F20xx 
features in between – like the "publicx" example of recently [instead of 
'public x' or 'public::x'; spaces aren't that expensive anymore].)


> gcc/fortran/ChangeLog

>

>     Jim MacArthur  <jim.macarthur@codethink.co.uk>

>     Mark Eggleston  <mark.eggleston@codethink.com>

>

>     * arith.c (hollerith2representation): Use 

> OPT_Wcharacter_truncation in

>     call to gfc_warning.  Add character2representation, 

> gfc_character2int,

>     gfc_character2real, gfc_character2complex and gfc_character2logical.

>     * arith.h: Add prototypes for gfc_character2int, gfc_character2real,

>     gfc_character2complex and gfc_character2logical.

>     * expr.c (gfc_check_assign): Return true if left hand side is numeric

>     or logical and the right hand side is character and of kind=1.

>     * gfortran.texi: Add -fdec-char-conversions.

>     * intrinsic.c (add_conversions): Add conversions from character to

>     integer, real, complex and logical types for their supported kinds.

>     (gfc_convert_type_warn): Reorder if..else if.. sequence so that 

> warnings

>     are produced for conversion to logical.

>     * invoke.texi: Add option to list of options.

>     * invoke.texi: Add Character conversion subsection to Extensions

>     section.

>     * lang.opt: Add new option.

>     * options.c (set_dec_flags): Add SET_BITFLAG for

>     flag_dec_char_conversions.

>     * resolve.c (resolve_ordindary_assign): Issue error if the left hand

>     side is numeric or logical and the right hand side is a character

>     variable.

>     * simplify.c (gfc_convert_constant): Assign the conversion function

>     depending on destination type.

>     * trans-const.c (gfc_constant_to_tree): Use OPT_Wsurprising in

>     gfc_warning allowing the warning to be switched off only if

>     flag_dec_char_conversions is enabled.

>

> gcc/testsuite/gfortran.dg

>

>     Jim MacArthur <jim.macarthur@codethink.co.uk>

>     Mark Eggleston <mark.eggleston@codethink.com>

>

>     PR fortran/89103

>     * gfortran.dg/dec_char_conversion_in_assignment_1.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_2.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_3.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_4.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_5.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_6.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_7.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_assignment_8.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_1.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_2.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_3.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_4.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_5.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_6.f90: New test.

>     * gfortran.dg/dec_char_conversion_in_data_7.f90: New test.

>     * gfortran.dg/hollerith5.f90: Add -Wsurprising to options.

>     * gfortran.dg/hollerith_legacy.f90: Add -Wsurprising to options.

>     * gfortran.dg/no_char_to_numeric_assign.f90: New test.
Steve Kargl Nov. 8, 2019, 2:35 p.m. | #6
On Fri, Nov 08, 2019 at 11:17:21AM +0100, Tobias Burnus wrote:
> Additionally, there are several recent reports on segfaults and 

> regressions, looking Bugzilla (component = fortran, sort by change data).

> 


Easiest way to find open gfortran bugs is through the gfortran wiki.
https://gcc.gnu.org/wiki/GFortran
Go down to the "For gfrtran developers" section.

-- 
steve
Jakub Jelinek Nov. 8, 2019, 4:52 p.m. | #7
On Fri, Nov 08, 2019 at 11:17:21AM +0100, Tobias Burnus wrote:
> >     Jim MacArthur  <jim.macarthur@codethink.co.uk>

> >     Mark Eggleston  <mark.eggleston@codethink.com>

> > 

> >     * arith.c (hollerith2representation): Use OPT_Wcharacter_truncation

> > in

> >     call to gfc_warning.  Add character2representation,

> > gfc_character2int,

> >     gfc_character2real, gfc_character2complex and gfc_character2logical.


This broke bootstrap:
../../gcc/fortran/arith.c: In function ‘void character2representation(gfc_expr*, gfc_expr*)’:
../../gcc/fortran/arith.c:2549:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
   for (i = 0; i < MIN (result_len, src_len); i++)

I have committed the following patch to unbreak it as obvious.
Also, the ChangeLog entry has various issues.  When adding new functions
or prototypes etc., it should be
	(character2representation, gfc_character2int, gfc_character2real,
	gfc_character2complex, gfc_character2logical): New.
(or New functions., New declarations., Declare. etc.), not Add ...
Always what has changed and what was the change.

> >     * invoke.texi: Add option to list of options.

> >     * invoke.texi: Add Character conversion subsection to Extensions

> >     section.


The same file shouldn't be listed multiple times in the same ChangeLog
entry, multiple changes should be merged together, plus it would be helpful
to say what option has been added, etc.

> >     * lang.opt: Add new option.


Here it should be even * lang.opt (fdec-char-conversions): New option.
or so.

	Jakub
Jakub Jelinek Nov. 9, 2019, midnight | #8
On Fri, Nov 08, 2019 at 11:17:21AM +0100, Tobias Burnus wrote:
> >     Jim MacArthur <jim.macarthur@codethink.co.uk>

> >     Mark Eggleston <mark.eggleston@codethink.com>

> > 

> >     PR fortran/89103

> >     * gfortran.dg/dec_char_conversion_in_assignment_1.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_2.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_3.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_4.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_5.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_6.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_7.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_assignment_8.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_1.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_2.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_3.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_4.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_5.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_6.f90: New test.

> >     * gfortran.dg/dec_char_conversion_in_data_7.f90: New test.

> >     * gfortran.dg/hollerith5.f90: Add -Wsurprising to options.

> >     * gfortran.dg/hollerith_legacy.f90: Add -Wsurprising to options.

> >     * gfortran.dg/no_char_to_numeric_assign.f90: New test.


After full bootstrap/regtest, I've also noticed:
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -O0  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -O1  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -O2  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -O3 -g  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_assignment_4.f90   -Os  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -O0  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -O1  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -O2  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -O3 -g  compilation failed to produce executable
+UNRESOLVED: gfortran.dg/dec_char_conversion_in_data_3.f90   -Os  compilation failed to produce executable

Tests with dg-error are expected to fail compilation, so won't produce
executable and thus can't be run.

Fixed thusly, tested on x86_64-linux, committed to trunk as obvious.

2019-11-09  Jakub Jelinek  <jakub@redhat.com>

	* gfortran.dg/dec_char_conversion_in_assignment_4.f90: Use
	dg-do compile instead of dg-do run.
	* gfortran.dg/dec_char_conversion_in_data_3.f90: Likewise.

--- testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90	(revision 277993)
+++ testsuite/gfortran.dg/dec_char_conversion_in_assignment_4.f90	(working copy)
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do compile }
 ! { dg-options "-fdec -fno-dec-char-conversions" }
 !
 ! Modified by Mark Eggleston <mark.eggleston@codethink.com>
@@ -17,4 +17,3 @@ include "dec_char_conversion_in_assignme
 ! { dg-error "Cannot convert" " " { target *-*-* } 47 }
 ! { dg-error "Cannot convert" " " { target *-*-* } 48 }
 ! { dg-error "Cannot convert" " " { target *-*-* } 49 }
-
--- testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90	(revision 277993)
+++ testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90	(working copy)
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do compile }
 ! { dg-options "-fdec -fno-dec-char-conversions" }
 !
 ! Modified by Mark Eggleston <mark.eggleston@codethink.com>
@@ -17,4 +17,3 @@ include "dec_char_conversion_in_data_1.f
 ! { dg-error "Incompatible types" " " { target *-*-* } 68 }
 ! { dg-error "Incompatible types" " " { target *-*-* } 69 }
 ! { dg-error "Incompatible types" " " { target *-*-* } 70 }
-


	Jakub

Patch

From 26a2a7f4a65331f519ced628dfe7e0fa7b3ce513 Mon Sep 17 00:00:00 2001
From: Jim MacArthur <jim.macarthur@codethink.co.uk>
Date: Thu, 4 Feb 2016 17:18:30 +0000
Subject: [PATCH] Allow CHARACTER literals in assignments and data statements

Warnings are raised when this happens.

Enable using -fdec-char-as-int or -fdec
---
 gcc/fortran/arith.c                                | 94 +++++++++++++++++++++-
 gcc/fortran/arith.h                                |  4 +
 gcc/fortran/expr.c                                 |  5 ++
 gcc/fortran/gfortran.texi                          | 24 ++++++
 gcc/fortran/intrinsic.c                            | 32 +++++++-
 gcc/fortran/invoke.texi                            | 17 ++--
 gcc/fortran/lang.opt                               |  5 ++
 gcc/fortran/options.c                              |  1 +
 gcc/fortran/resolve.c                              |  9 +++
 gcc/fortran/simplify.c                             | 29 ++++++-
 gcc/fortran/trans-const.c                          |  6 +-
 .../dec_char_conversion_in_assignment_1.f90        | 61 ++++++++++++++
 .../dec_char_conversion_in_assignment_2.f90        | 61 ++++++++++++++
 .../dec_char_conversion_in_assignment_3.f90        | 61 ++++++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_1.f90  | 69 ++++++++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_2.f90  | 69 ++++++++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_3.f90  | 69 ++++++++++++++++
 .../gfortran.dg/dec_char_conversion_in_data_4.f90  |  9 +++
 gcc/testsuite/gfortran.dg/hollerith5.f90           |  5 +-
 gcc/testsuite/gfortran.dg/hollerith_legacy.f90     |  2 +-
 .../gfortran.dg/no_char_to_numeric_assign.f90      | 21 +++++
 21 files changed, 634 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90

diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index ff279db4992..ad071c71c3f 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -2510,9 +2510,9 @@  hollerith2representation (gfc_expr *result, gfc_expr *src)
 
   if (src_len > result_len)
     {
-      gfc_warning (0,
-		   "The Hollerith constant at %L is too long to convert to %qs",
-		   &src->where, gfc_typename(&result->ts));
+      gfc_warning (OPT_Wcharacter_truncation, "The Hollerith constant at %L "
+		   "is truncated in conversion to %qs", &src->where,
+		   gfc_typename(&result->ts));
     }
 
   result->representation.string = XCNEWVEC (char, result_len + 1);
@@ -2527,6 +2527,36 @@  hollerith2representation (gfc_expr *result, gfc_expr *src)
 }
 
 
+/* Helper function to set the representation in a character conversion.
+   This assumes that the ts.type and ts.kind of the result have already
+   been set.  */
+
+static void
+character2representation (gfc_expr *result, gfc_expr *src)
+{
+  size_t src_len, result_len;
+  int i;
+  src_len = src->value.character.length;
+  gfc_target_expr_size (result, &result_len);
+
+  if (src_len > result_len)
+    gfc_warning (OPT_Wcharacter_truncation, "The character constant at %L is "
+		 "is truncated in conversion to %s", &src->where,
+		 gfc_typename(&result->ts));
+
+  result->representation.string = XCNEWVEC (char, result_len + 1);
+
+  for (i = 0; i < MIN (result_len, src_len); i++)
+    result->representation.string[i] = (char) src->value.character.string[i];
+
+  if (src_len < result_len)
+    memset (&result->representation.string[src_len], ' ',
+	    result_len - src_len);
+
+  result->representation.string[result_len] = '\0'; /* For debugger  */
+  result->representation.length = result_len;
+}
+
 /* Convert Hollerith to integer. The constant will be padded or truncated.  */
 
 gfc_expr *
@@ -2542,6 +2572,19 @@  gfc_hollerith2int (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to integer. The constant will be padded or truncated. */
+
+gfc_expr *
+gfc_character2int (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_integer (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, result->value.integer);
+  return result;
+}
 
 /* Convert Hollerith to real. The constant will be padded or truncated.  */
 
@@ -2558,6 +2601,21 @@  gfc_hollerith2real (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to real. The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2real (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_float (kind, (unsigned char *) result->representation.string,
+		       result->representation.length, result->value.real);
+
+  return result;
+}
+
 
 /* Convert Hollerith to complex. The constant will be padded or truncated.  */
 
@@ -2574,6 +2632,21 @@  gfc_hollerith2complex (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert character to complex. The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2complex (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_complex (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, result->value.complex);
+
+  return result;
+}
+
 
 /* Convert Hollerith to character.  */
 
@@ -2609,3 +2682,18 @@  gfc_hollerith2logical (gfc_expr *src, int kind)
 
   return result;
 }
+
+/* Convert character to logical. The constant will be padded or truncated.  */
+
+gfc_expr *
+gfc_character2logical (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where);
+
+  character2representation (result, src);
+  gfc_interpret_logical (kind, (unsigned char *) result->representation.string,
+			 result->representation.length, &result->value.logical);
+
+  return result;
+}
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index 39366caaba1..85c8b8cef41 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -77,7 +77,11 @@  gfc_expr *gfc_hollerith2real (gfc_expr *, int);
 gfc_expr *gfc_hollerith2complex (gfc_expr *, int);
 gfc_expr *gfc_hollerith2character (gfc_expr *, int);
 gfc_expr *gfc_hollerith2logical (gfc_expr *, int);
+gfc_expr *gfc_character2int (gfc_expr *, int);
+gfc_expr *gfc_character2real (gfc_expr *, int);
+gfc_expr *gfc_character2complex (gfc_expr *, int);
 gfc_expr *gfc_character2character (gfc_expr *, int);
+gfc_expr *gfc_character2logical (gfc_expr *, int);
 
 #endif /* GFC_ARITH_H  */
 
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index c508890d68d..f04d19f7409 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3722,6 +3722,11 @@  gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform,
 	  || rvalue->ts.type == BT_HOLLERITH)
 	return true;
 
+      if (flag_dec_char_conversions && (gfc_numeric_ts (&lvalue->ts)
+	  || lvalue->ts.type == BT_LOGICAL)
+          && rvalue->ts.type == BT_CHARACTER)
+	return true;
+
       if (lvalue->ts.type == BT_LOGICAL && rvalue->ts.type == BT_LOGICAL)
 	return true;
 
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 02d30e19660..8341bcda199 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -1600,6 +1600,7 @@  additional compatibility extensions along with those enabled by
 * Unary operators::
 * Implicitly convert LOGICAL and INTEGER values::
 * Hollerith constants support::
+* Character conversion::
 * Cray pointers::
 * CONVERT specifier::
 * OpenMP::
@@ -1955,6 +1956,29 @@  obtained by using the @code{TRANSFER} statement, as in this example.
 @end smallexample
 
 
+@node Character conversion
+@subsection Character conversion
+@cindex conversion, to character
+
+Allowing character literals to be used in a similar way to Hollerith constants
+is a non-standard extension.
+
+Character literals can be used in @code{DATA} statements and assignments with
+numeric (@code{INTEGER}, @code{REAL}, or @code{COMPLEX}) or @code{LOGICAL}
+variables. Like Hollerith constants they are copied byte-wise fashion. The
+constant will be padded with spaces or truncated to fit the size of the
+variable in which it is stored.
+
+Examples:
+@smallexample
+      integer*4 x
+      data x / 'abcd' /
+
+      x = 'A'       ! Will be padded.
+      x = 'ab1234'  ! Will be truncated.
+@end smallexample
+
+
 @node Cray pointers
 @subsection Cray pointers
 @cindex pointer, Cray
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index ac5af10a775..9cfbac363bf 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -4025,6 +4025,28 @@  add_conversions (void)
 	  add_conv (BT_LOGICAL, gfc_logical_kinds[j].kind,
 		    BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
 	}
+
+  /* Flang allows character conversions similar to Hollerith conversions
+     - the first characters will be turned into ascii values. */
+  if (flag_dec_char_conversions)
+    {
+      /* Character-Integer conversions.  */
+      for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Real conversions.  */
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_REAL, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Complex conversions.  */
+      for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_COMPLEX, gfc_real_kinds[i].kind, GFC_STD_LEGACY);
+      /* Character-Logical conversions.  */
+      for (i = 0; gfc_logical_kinds[i].kind != 0; i++)
+	add_conv (BT_CHARACTER, gfc_default_character_kind,
+		  BT_LOGICAL, gfc_logical_kinds[i].kind, GFC_STD_LEGACY);
+    }
 }
 
 
@@ -5185,8 +5207,16 @@  gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 			     gfc_typename (&from_ts), gfc_dummy_typename (ts),
 			     &expr->where);
 	}
+      else if (flag_dec_char_conversions && from_ts.type == BT_CHARACTER
+	       && (gfc_numeric_ts (ts) || ts->type == BT_LOGICAL))
+	{
+	  const char *type_name = is_char_constant ? gfc_typename (expr)
+						   : gfc_typename (&from_ts);
+	  gfc_warning_now (OPT_Wconversion, "Conversion from %s to %s at %L",
+			   type_name, gfc_typename (ts), &expr->where);
+	}
       else
-        gcc_unreachable ();
+	gcc_unreachable ();
     }
 
   /* Insert a pre-resolved function call to the right function.  */
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index fa60effdbfe..4d01ddeaa07 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -118,9 +118,9 @@  by type.  Explanations are in the following sections.
 @xref{Fortran Dialect Options,,Options controlling Fortran dialect}.
 @gccoptlist{-fall-intrinsics -fallow-argument-mismatch -fallow-invalid-boz @gol
 -fbackslash -fcray-pointer -fd-lines-as-code -fd-lines-as-comments -fdec @gol
--fdec-structure-fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol
--fdec-format-defaults -fdec-blank-format-item -fdefault-double-8 @gol
--fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 @gol
+-fdec-char-conversions -fdec-structure -fdec-intrinsic-ints -fdec-static @gol
+-fdec-math -fdec-include -fdec-format-defaults -fdec-blank-format-item @gol
+-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 @gol
 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -fpad-source -ffree-form @gol
 -ffree-line-length-@var{n} -ffree-line-length-none -fimplicit-none @gol
@@ -272,14 +272,19 @@  For details on GNU Fortran's implementation of these extensions see the
 full documentation.
 
 Other flags enabled by this switch are:
-@option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-structure}
-@option{-fdec-intrinsic-ints} @option{-fdec-static} @option{-fdec-math}
-@option{-fdec-include} @option{-fdec-blank-format-item}
+@option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-char-conversions}
+@option{-fdec-structure} @option{-fdec-intrinsic-ints} @option{-fdec-static}
+@option{-fdec-math} @option{-fdec-include} @option{-fdec-blank-format-item}
 @option{-fdec-format-defaults}
 
 If @option{-fd-lines-as-code}/@option{-fd-lines-as-comments} are unset, then
 @option{-fdec} also sets @option{-fd-lines-as-comments}.
 
+@item -fdec-char-conversions
+@opindex @code{fdec-char-conversions}
+Enable the use of character literals in assignments and data statements
+for non-character variables.
+
 @item -fdec-structure
 @opindex @code{fdec-structure}
 Enable DEC @code{STRUCTURE} and @code{RECORD} as well as @code{UNION},
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 2cfc76df2ab..a6e73e1292d 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -456,6 +456,11 @@  fdec-blank-format-item
 Fortran Var(flag_dec_blank_format_item)
 Enable the use of blank format items in format strings.
 
+fdec-char-conversions
+Fortran Var(flag_dec_char_conversions)
+Enable the use of character literals in assignments and data statements
+for non-character variables.
+
 fdec-include
 Fortran Var(flag_dec_include)
 Enable legacy parsing of INCLUDE as statement.
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 771c10e4985..6d5bc0655f8 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -76,6 +76,7 @@  set_dec_flags (int value)
   SET_BITFLAG (flag_dec_include, value, value);
   SET_BITFLAG (flag_dec_format_defaults, value, value);
   SET_BITFLAG (flag_dec_blank_format_item, value, value);
+  SET_BITFLAG (flag_dec_char_conversions, value, value);
 }
 
 /* Finalize DEC flags.  */
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 93f2d0aa761..c824a6b7ac1 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -10689,6 +10689,15 @@  resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
   lhs = code->expr1;
   rhs = code->expr2;
 
+  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)
+      && rhs->ts.type == BT_CHARACTER
+      && rhs->expr_type != EXPR_CONSTANT)
+    {
+      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),
+		 gfc_typename (lhs), &rhs->where);
+      return false;
+    }
+
   /* Handle the case of a BOZ literal on the RHS.  */
   if (rhs->ts.type == BT_BOZ)
     {
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index fa5aefe20c6..2eb1943c3ee 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -8522,10 +8522,31 @@  gfc_convert_constant (gfc_expr *e, bt type, int kind)
       break;
 
     case BT_CHARACTER:
-      if (type == BT_CHARACTER)
-	f = gfc_character2character;
-      else
-	goto oops;
+      switch (type)
+	{
+	case BT_INTEGER:
+	  f = gfc_character2int;
+	  break;
+
+	case BT_REAL:
+	  f = gfc_character2real;
+	  break;
+
+	case BT_COMPLEX:
+	  f = gfc_character2complex;
+	  break;
+
+	case BT_CHARACTER:
+	  f = gfc_character2character;
+	  break;
+
+	case BT_LOGICAL:
+	  f = gfc_character2logical;
+	  break;
+
+	default:
+	  goto oops;
+	}
       break;
 
     default:
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
index 432d12bf168..e4df0a7b1a5 100644
--- a/gcc/fortran/trans-const.c
+++ b/gcc/fortran/trans-const.c
@@ -25,6 +25,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tree.h"
 #include "gfortran.h"
+#include "options.h"
 #include "trans.h"
 #include "fold-const.h"
 #include "stor-layout.h"
@@ -331,8 +332,9 @@  gfc_conv_constant_to_tree (gfc_expr * expr)
 			gfc_build_string_const (expr->representation.length,
 						expr->representation.string));
 	  if (!integer_zerop (tmp) && !integer_onep (tmp))
-	    gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"
-			 " has undefined result at %L", &expr->where);
+	    gfc_warning (OPT_Wsurprising, "Assigning value other than 0 or 1 "
+		         "to LOGICAL has undefined result at %L",
+			 &expr->where);
 	  return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
 	}
       else
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
new file mode 100644
index 00000000000..d504f92fbbc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_1.f90
@@ -0,0 +1,61 @@ 
+! { dg-do run }
+! { dg-options "-fdec -Wsurprising -Wcharacter-truncation" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  a = '1234'
+  b = '1234'
+  c = '12341234'
+  d = '1234'     ! { dg-warning "undefined result" }
+  e = 4h1234
+  f = 4h1234
+  g = 8h12341234
+  h = 4h1234     ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+
+  ! padded values
+  a = '12'
+  b = '12'
+  c = '12234'
+  d = '124'   ! { dg-warning "undefined result" }
+  e = 2h12
+  f = 2h12
+  g = 5h12234
+  h = 3h123   ! { dg-warning "undefined result" }
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+  ! truncated values
+  a = '123478'       ! { dg-warning "truncated in" }
+  b = '123478'       ! { dg-warning "truncated in" }
+  c = '12341234987'  ! { dg-warning "truncated in" }
+  d = '1234abc'      ! { dg-warning "truncated in|undefined result" }
+  e = 6h123478       ! { dg-warning "truncated in" }
+  f = 6h123478       ! { dg-warning "truncated in" }
+  g = 11h12341234987 ! { dg-warning "truncated in" }
+  h = 7h1234abc      ! { dg-warning "truncated in|undefined result" }
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+end program
+
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
new file mode 100644
index 00000000000..737ddc664de
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_2.f90
@@ -0,0 +1,61 @@ 
+! { dg-do run }
+! { dg-options "-fdec-char-conversions -std=legacy -Wcharacter-truncation -Wsurprising" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  a = '1234'
+  b = '1234'
+  c = '12341234'
+  d = '1234'     ! { dg-warning "undefined result" }
+  e = 4h1234
+  f = 4h1234
+  g = 8h12341234
+  h = 4h1234     ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+
+  ! padded values
+  a = '12'
+  b = '12'
+  c = '12234'
+  d = '124'   ! { dg-warning "undefined result" }
+  e = 2h12
+  f = 2h12
+  g = 5h12234
+  h = 3h123   ! { dg-warning "undefined result" }
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+  ! truncated values
+  a = '123478'       ! { dg-warning "truncated in" }
+  b = '123478'       ! { dg-warning "truncated in" }
+  c = '12341234987'  ! { dg-warning "truncated in" }
+  d = '1234abc'      ! { dg-warning "truncated in|undefined result" }
+  e = 6h123478       ! { dg-warning "truncated in" }
+  f = 6h123478       ! { dg-warning "truncated in" }
+  g = 11h12341234987 ! { dg-warning "truncated in" }
+  h = 7h1234abc      ! { dg-warning "truncated in|undefined result" }
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+end program
+
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
new file mode 100644
index 00000000000..0ec494c4a92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_assignment_3.f90
@@ -0,0 +1,61 @@ 
+! { dg-do run }
+! { dg-options "-fdec -fno-dec-char-conversions" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  a = '1234'     ! { dg-error "Cannot convert" }
+  b = '1234'     ! { dg-error "Cannot convert" }
+  c = '12341234' ! { dg-error "Cannot convert" }
+  d = '1234'     ! { dg-error "Cannot convert" }
+  e = 4h1234
+  f = 4h1234
+  g = 8h12341234
+  h = 4h1234
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+
+  ! padded values
+  a = '12'    ! { dg-error "Cannot convert" }
+  b = '12'    ! { dg-error "Cannot convert" }
+  c = '12234' ! { dg-error "Cannot convert" }
+  d = '124'   ! { dg-error "Cannot convert" }
+  e = 2h12
+  f = 2h12
+  g = 5h12234
+  h = 3h123
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+  ! truncated values
+  a = '123478'       ! { dg-error "Cannot convert" }
+  b = '123478'       ! { dg-error "Cannot convert" }
+  c = '12341234987'  ! { dg-error "Cannot convert" }
+  d = '1234abc'      ! { dg-error "Cannot convert" }
+  e = 6h123478       !
+  f = 6h123478       !
+  g = 11h12341234987 !
+  h = 7h1234abc      !
+
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+
+end program
+
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
new file mode 100644
index 00000000000..c493be9314b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_1.f90
@@ -0,0 +1,69 @@ 
+! { dg-do run }
+! { dg-options "-fdec -Wsurprising" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+subroutine normal
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-warning "undefined result" }
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 / ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+end subroutine
+
+subroutine padded
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-warning "undefined result" }
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 / ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+end subroutine
+
+subroutine truncated
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-warning "too long|undefined result" }
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 / ! { dg-warning "too long|undefined result" }
+  
+  if (a.ne.e) stop 9
+  if (b.ne.f) stop 10
+  if (c.ne.g) stop 11
+  if (d.neqv.h) stop 12
+end subroutine
+
+program test
+  call normal
+  call padded
+  call truncated
+end program
+
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
new file mode 100644
index 00000000000..c7d8e241cec
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_2.f90
@@ -0,0 +1,69 @@ 
+! { dg-do run }
+! { dg-options "-fdec-char-conversions -std=legacy -Wsurprising" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+subroutine normal
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-warning "undefined result" }
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 / ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+end subroutine
+
+subroutine padded
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-warning "undefined result" }
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 / ! { dg-warning "undefined result" }
+  
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+end subroutine
+
+subroutine truncated
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-warning "too long|undefined result" }
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 / ! { dg-warning "too long|undefined result" }
+  
+  if (a.ne.e) stop 9
+  if (b.ne.f) stop 10
+  if (c.ne.g) stop 11
+  if (d.neqv.h) stop 12
+end subroutine
+
+program test
+  call normal
+  call padded
+  call truncated
+end program
+
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
new file mode 100644
index 00000000000..e7d084b5ffc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_3.f90
@@ -0,0 +1,69 @@ 
+! { dg-do run }
+! { dg-options "-fdec -fno-dec-char-conversions" }
+!
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+subroutine normal
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '1234', '1234', '12341234', '1234' / ! { dg-error "Incompatible types" }
+  data e, f, g, h / 4h1234, 4h1234, 8h12341234, 4h1234 /
+  
+  if (a.ne.e) stop 1
+  if (b.ne.f) stop 2
+  if (c.ne.g) stop 3
+  if (d.neqv.h) stop 4
+end subroutine
+
+subroutine padded
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '12', '12', '12334', '123' / ! { dg-error "Incompatible types" }
+  data e, f, g, h / 2h12, 2h12, 5h12334, 3h123 /
+  
+  if (a.ne.e) stop 5
+  if (b.ne.f) stop 6
+  if (c.ne.g) stop 7
+  if (d.neqv.h) stop 8
+end subroutine
+
+subroutine truncated
+  integer(4) :: a
+  real(4) :: b
+  complex(4) :: c
+  logical(4) :: d
+  integer(4) :: e
+  real(4) :: f
+  complex(4) :: g
+  logical(4) :: h
+
+  data a, b, c, d / '123478', '123478', '1234123498', '12345' /  ! { dg-error "Incompatible types" }
+  data e, f, g, h / 6h123478, 6h123478, 10h1234123498, 5h12345 /
+  
+  if (a.ne.e) stop 9
+  if (b.ne.f) stop 10
+  if (c.ne.g) stop 11
+  if (d.neqv.h) stop 12
+end subroutine
+
+program test
+  call normal
+  call padded
+  call truncated
+end program
+
diff --git a/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90 b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
new file mode 100644
index 00000000000..6eff27e14bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_char_conversion_in_data_4.f90
@@ -0,0 +1,9 @@ 
+! { dg-do compile }
+! { dg-options "-fdec -Wconversion" }
+!
+! Ensure that character type name is correctly reported.
+
+program test
+  integer(4) x
+  data x / 'ABCD' / ! { dg-warning "CHARACTER\\(4\\) to INTEGER\\(4\\)" }
+end program
diff --git a/gcc/testsuite/gfortran.dg/hollerith5.f90 b/gcc/testsuite/gfortran.dg/hollerith5.f90
index ebd0a117c4f..d17f9ae40cf 100644
--- a/gcc/testsuite/gfortran.dg/hollerith5.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith5.f90
@@ -1,8 +1,9 @@ 
        ! { dg-do compile }
+       ! { dg-options "-Wsurprising" }
        implicit none
        logical b
        b = 4Habcd ! { dg-warning "has undefined result" }
        end
 
-! { dg-warning "Hollerith constant" "const" { target *-*-* } 4 }
-! { dg-warning "Conversion" "conversion" { target *-*-* } 4 }
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 5 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 5 }
diff --git a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90 b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
index c3322498345..9d7e989b552 100644
--- a/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith_legacy.f90
@@ -1,5 +1,5 @@ 
 ! { dg-do compile }
-! { dg-options "-std=legacy" }
+! { dg-options "-std=legacy -Wsurprising" }
 ! PR15966, PR18781 & PR16531
 implicit none
 complex(kind=8) x(2) 
diff --git a/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90 b/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90
new file mode 100644
index 00000000000..3c60403160a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/no_char_to_numeric_assign.f90
@@ -0,0 +1,21 @@ 
+! { dg-do compile }
+! { dg-options "-fdec-char-conversions" }
+!
+! Test character variables can not be assigned to numeric and
+! logical variables.
+!
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+program test
+  integer a
+  real b
+  complex c
+  logical d
+  character e
+
+  e = "A"
+  a = e ! { dg-error "Cannot convert" }
+  b = e ! { dg-error "Cannot convert" }
+  c = e ! { dg-error "Cannot convert" }
+  d = e ! { dg-error "Cannot convert" }
+end program
-- 
2.11.0