diff options
author | Mark Eggleston <mark.eggleston@codethink.com> | 2019-11-08 14:28:57 +0000 |
---|---|---|
committer | Mark Eggleston <markeggleston@gcc.gnu.org> | 2019-11-08 14:28:57 +0000 |
commit | 2afeb1ca38dbb7c8708272452417426e46b4d6ed (patch) | |
tree | 64a5d856971870bc05da3d569128a278bcffa3a5 /gcc/fortran/intrinsic.c | |
parent | 4e9d58d16767b1bc686f0c4b3bd2da25dc71e8f3 (diff) | |
download | gcc-2afeb1ca38dbb7c8708272452417426e46b4d6ed.zip gcc-2afeb1ca38dbb7c8708272452417426e46b4d6ed.tar.gz gcc-2afeb1ca38dbb7c8708272452417426e46b4d6ed.tar.bz2 |
Allow CHARACTER literals in assignments and data statements.
Allows character literals to used to assign values to non-character variables
in the same way that Hollerith constants are used. In addition character
literals can be used in data statements just like Hollerith constants.
Warnings of such use are output to discourage this usage as it is a non-standard
legacy feature and must be explicitly enabled.
Enabled by -fdec and -fdec-char-conversions.
Co-Authored-By: Jim MacArthur <jim.macarthur@codethink.co.uk>
From-SVN: r277975
Diffstat (limited to 'gcc/fortran/intrinsic.c')
-rw-r--r-- | gcc/fortran/intrinsic.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index ac5af10..572967f 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 */ } |