re PR fortran/47359 (Recursive functions of intrinsic names generates invalid assembler)

2015-06-06  Thomas Koenig  <tkoenig@netcologne.de>

	PR fortran/47359
	* arith.c (eval_intrinsic_op): Set warn flag for
	gfc_type_convert_binary if -Wconversion or -Wconversion-extra
	are set.
	(wprecision_real_real): New function.
	(wprecision_int_real): New function.
	(gfc_int2int): If -fno-range-check and -Wconversion are specified
	and it is a narrowing conversion, warn.
	(gfc_int2real): If there is a change in value for the conversion,
	warn.
	(gfc_int2complex):  Likewise.
	(gfc_real2int): If there is a fractional part to the real number,
	warn with -Wconversion, otherwise warn with -Wconversion-extra.
	(gfc_real2real): Emit warning if the constant was changed by
	conversion with either -Wconversion or -Wconversion-extra.  With
	-Wconversion-extra, warn if no warning was issued earlier.
	(gfc_real2complex):  Likewise.
	(gfc_complex2int): For -Wconversion or -Wconversion-extra, if
	there was an imaginary part, warn; otherwise, warn for change in
	value.  Warn with -Wconversion-extra if no other warning was
	issued.
	(gfc_complex2real): For -Wconversion or -Wconversion-extra, if
	there was an imaginary part, warn; otherwise, warn for change in
	value. Warn with -Wconversion-extra if no other warning was
	issued.
	(gfc_complex2complex):  For -Wconversion, warn if the value of
	either the real or the imaginary part was changed.  Warn for
	-Wconversion-extra if no prior warning was issued.
	* expr.c (gfc_check_assign):  Remove check for change in value.
	* primary.c (match_real_constant): For -Wconversion-extra, check
	against a number in which the last non-zero digit has been
	replaced with a zero.  If the number compares equal, warn.
	* intrinsic.c (gfc_convert_type_warn):  Do not warn about constant
	conversions.

2015-06-06  Thomas Koenig  <tkoenig@netcologne.de>

	PR fortran/47359
	* gfortran.dg/array_constructor_type_17.f03: Adjust error message.
	* gfortran.dg/warn_conversion.f90: Add warning for change in value
	for assignment.
	* gfortran.dg/warn_conversion_3.f90: Add warnings.
	* gfortran.dg/warn_conversion_5.f90: New test.
	* gfortran.dg/warn_conversion_6.f90: New test.
	* gfortran.dg/warn_conversion_7.f90: New test.

From-SVN: r224190
This commit is contained in:
Thomas Koenig 2015-06-06 16:12:39 +00:00 committed by Thomas Koenig
parent 5a7929c860
commit cbf560d708
12 changed files with 408 additions and 65 deletions

View File

@ -1,3 +1,40 @@
2015-06-06 Thomas Koenig <tkoenig@netcologne.de>
PR fortran/47359
* arith.c (eval_intrinsic_op): Set warn flag for
gfc_type_convert_binary if -Wconversion or -Wconversion-extra
are set.
(wprecision_real_real): New function.
(wprecision_int_real): New function.
(gfc_int2int): If -fno-range-check and -Wconversion are specified
and it is a narrowing conversion, warn.
(gfc_int2real): If there is a change in value for the conversion,
warn.
(gfc_int2complex): Likewise.
(gfc_real2int): If there is a fractional part to the real number,
warn with -Wconversion, otherwise warn with -Wconversion-extra.
(gfc_real2real): Emit warning if the constant was changed by
conversion with either -Wconversion or -Wconversion-extra. With
-Wconversion-extra, warn if no warning was issued earlier.
(gfc_real2complex): Likewise.
(gfc_complex2int): For -Wconversion or -Wconversion-extra, if
there was an imaginary part, warn; otherwise, warn for change in
value. Warn with -Wconversion-extra if no other warning was
issued.
(gfc_complex2real): For -Wconversion or -Wconversion-extra, if
there was an imaginary part, warn; otherwise, warn for change in
value. Warn with -Wconversion-extra if no other warning was
issued.
(gfc_complex2complex): For -Wconversion, warn if the value of
either the real or the imaginary part was changed. Warn for
-Wconversion-extra if no prior warning was issued.
* expr.c (gfc_check_assign): Remove check for change in value.
* primary.c (match_real_constant): For -Wconversion-extra, check
against a number in which the last non-zero digit has been
replaced with a zero. If the number compares equal, warn.
* intrinsic.c (gfc_convert_type_warn): Do not warn about constant
conversions.
2015-06-05 Steven G. Kargl <kargl@gcc.gnu.org> 2015-06-05 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/66347 PR fortran/66347

View File

@ -1521,7 +1521,7 @@ eval_intrinsic (gfc_intrinsic_op op,
temp.value.op.op1 = op1; temp.value.op.op1 = op1;
temp.value.op.op2 = op2; temp.value.op.op2 = op2;
gfc_type_convert_binary (&temp, 0); gfc_type_convert_binary (&temp, warn_conversion || warn_conversion_extra);
if (op == INTRINSIC_EQ || op == INTRINSIC_NE if (op == INTRINSIC_EQ || op == INTRINSIC_NE
|| op == INTRINSIC_GE || op == INTRINSIC_GT || op == INTRINSIC_GE || op == INTRINSIC_GT
@ -1949,6 +1949,42 @@ arith_error (arith rc, gfc_typespec *from, gfc_typespec *to, locus *where)
NaN, etc. */ NaN, etc. */
} }
/* Returns true if significant bits were lost when converting real
constant r from from_kind to to_kind. */
static bool
wprecision_real_real (mpfr_t r, int from_kind, int to_kind)
{
mpfr_t rv, diff;
bool ret;
gfc_set_model_kind (to_kind);
mpfr_init (rv);
gfc_set_model_kind (from_kind);
mpfr_init (diff);
mpfr_set (rv, r, GFC_RND_MODE);
mpfr_sub (diff, rv, r, GFC_RND_MODE);
ret = ! mpfr_zero_p (diff);
mpfr_clear (rv);
mpfr_clear (diff);
return ret;
}
/* Return true if conversion from an integer to a real loses precision. */
static bool
wprecision_int_real (mpz_t n, mpfr_t r)
{
mpz_t i;
mpz_init (i);
mpfr_get_z (i, r, GFC_RND_MODE);
mpz_sub (i, i, n);
return mpz_cmp_si (i, 0) != 0;
mpz_clear (i);
}
/* Convert integers to integers. */ /* Convert integers to integers. */
@ -1985,8 +2021,12 @@ gfc_int2int (gfc_expr *src, int kind)
k = gfc_validate_kind (BT_INTEGER, kind, false); k = gfc_validate_kind (BT_INTEGER, kind, false);
gfc_convert_mpz_to_signed (result->value.integer, gfc_convert_mpz_to_signed (result->value.integer,
gfc_integer_kinds[k].bit_size); gfc_integer_kinds[k].bit_size);
}
if (warn_conversion && kind < src->ts.kind)
gfc_warning_now (OPT_Wconversion, "Conversion from %qs to %qs at %L",
gfc_typename (&src->ts), gfc_typename (&result->ts),
&src->where);
}
return result; return result;
} }
@ -2010,6 +2050,14 @@ gfc_int2real (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if (warn_conversion
&& wprecision_int_real (src->value.integer, result->value.real))
gfc_warning_now (OPT_Wconversion, "Change of value in conversion "
"from %qs to %qs at %L",
gfc_typename (&src->ts),
gfc_typename (&result->ts),
&src->where);
return result; return result;
} }
@ -2034,6 +2082,15 @@ gfc_int2complex (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if (warn_conversion
&& wprecision_int_real (src->value.integer,
mpc_realref (result->value.complex)))
gfc_warning_now (OPT_Wconversion, "Change of value in conversion "
"from %qs to %qs at %L",
gfc_typename (&src->ts),
gfc_typename (&result->ts),
&src->where);
return result; return result;
} }
@ -2045,6 +2102,7 @@ gfc_real2int (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
@ -2057,6 +2115,28 @@ gfc_real2int (gfc_expr *src, int kind)
return NULL; return NULL;
} }
/* If there was a fractional part, warn about this. */
if (warn_conversion)
{
mpfr_t f;
mpfr_init (f);
mpfr_frac (f, src->value.real, GFC_RND_MODE);
if (mpfr_cmp_si (f, 0) != 0)
{
gfc_warning_now (OPT_Wconversion, "Change of value in conversion "
"from %qs to %qs at %L", gfc_typename (&src->ts),
gfc_typename (&result->ts), &src->where);
did_warn = true;
}
}
if (!did_warn && warn_conversion_extra)
{
gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs "
"at %L", gfc_typename (&src->ts),
gfc_typename (&result->ts), &src->where);
}
return result; return result;
} }
@ -2068,6 +2148,7 @@ gfc_real2real (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_REAL, kind, &src->where); result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
@ -2088,6 +2169,33 @@ gfc_real2real (gfc_expr *src, int kind)
return NULL; return NULL;
} }
/* As a special bonus, don't warn about REAL values which are not changed by
the conversion if -Wconversion is specified and -Wconversion-extra is
not. */
if ((warn_conversion || warn_conversion_extra) && src->ts.kind > kind)
{
int w = warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra;
/* Calculate the difference between the constant and the rounded
value and check it against zero. */
if (wprecision_real_real (src->value.real, src->ts.kind, kind))
{
gfc_warning_now (w, "Change of value in conversion from "
"%qs to %qs at %L",
gfc_typename (&src->ts), gfc_typename (&result->ts),
&src->where);
/* Make sure the conversion warning is not emitted again. */
did_warn = true;
}
}
if (!did_warn && warn_conversion_extra)
gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs "
"at %L", gfc_typename(&src->ts),
gfc_typename(&result->ts), &src->where);
return result; return result;
} }
@ -2099,6 +2207,7 @@ gfc_real2complex (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
@ -2119,6 +2228,26 @@ gfc_real2complex (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if ((warn_conversion || warn_conversion_extra) && src->ts.kind > kind)
{
int w = warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra;
if (wprecision_real_real (src->value.real, src->ts.kind, kind))
{
gfc_warning_now (w, "Change of value in conversion from "
"%qs to %qs at %L",
gfc_typename (&src->ts), gfc_typename (&result->ts),
&src->where);
/* Make sure the conversion warning is not emitted again. */
did_warn = true;
}
}
if (!did_warn && warn_conversion_extra)
gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs "
"at %L", gfc_typename(&src->ts),
gfc_typename(&result->ts), &src->where);
return result; return result;
} }
@ -2130,6 +2259,7 @@ gfc_complex2int (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
@ -2143,6 +2273,43 @@ gfc_complex2int (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if (warn_conversion || warn_conversion_extra)
{
int w = warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra;
/* See if we discarded an imaginary part. */
if (mpfr_cmp_si (mpc_imagref (src->value.complex), 0) != 0)
{
gfc_warning_now (w, "Non-zero imaginary part discarded "
"in conversion from %qs to %qs at %L",
gfc_typename(&src->ts), gfc_typename (&result->ts),
&src->where);
did_warn = true;
}
else {
mpfr_t f;
mpfr_init (f);
mpfr_frac (f, src->value.real, GFC_RND_MODE);
if (mpfr_cmp_si (f, 0) != 0)
{
gfc_warning_now (w, "Change of value in conversion from "
"%qs to %qs at %L", gfc_typename (&src->ts),
gfc_typename (&result->ts), &src->where);
did_warn = true;
}
mpfr_clear (f);
}
if (!did_warn && warn_conversion_extra)
{
gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs "
"at %L", gfc_typename (&src->ts),
gfc_typename (&result->ts), &src->where);
}
}
return result; return result;
} }
@ -2154,6 +2321,7 @@ gfc_complex2real (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_REAL, kind, &src->where); result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
@ -2174,6 +2342,41 @@ gfc_complex2real (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if (warn_conversion || warn_conversion_extra)
{
int w = warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra;
/* See if we discarded an imaginary part. */
if (mpfr_cmp_si (mpc_imagref (src->value.complex), 0) != 0)
{
gfc_warning_now (w, "Non-zero imaginary part discarded "
"in conversion from %qs to %qs at %L",
gfc_typename(&src->ts), gfc_typename (&result->ts),
&src->where);
did_warn = true;
}
/* Calculate the difference between the real constant and the rounded
value and check it against zero. */
if (kind > src->ts.kind
&& wprecision_real_real (mpc_realref (src->value.complex),
src->ts.kind, kind))
{
gfc_warning_now (w, "Change of value in conversion from "
"%qs to %qs at %L",
gfc_typename (&src->ts), gfc_typename (&result->ts),
&src->where);
/* Make sure the conversion warning is not emitted again. */
did_warn = true;
}
}
if (!did_warn && warn_conversion_extra)
gfc_warning_now (OPT_Wconversion, "Conversion from %qs to %qs at %L",
gfc_typename(&src->ts), gfc_typename (&result->ts),
&src->where);
return result; return result;
} }
@ -2185,6 +2388,7 @@ gfc_complex2complex (gfc_expr *src, int kind)
{ {
gfc_expr *result; gfc_expr *result;
arith rc; arith rc;
bool did_warn = false;
result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
@ -2220,6 +2424,26 @@ gfc_complex2complex (gfc_expr *src, int kind)
return NULL; return NULL;
} }
if ((warn_conversion || warn_conversion_extra) && src->ts.kind > kind
&& (wprecision_real_real (mpc_realref (src->value.complex),
src->ts.kind, kind)
|| wprecision_real_real (mpc_imagref (src->value.complex),
src->ts.kind, kind)))
{
int w = warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra;
gfc_warning_now (w, "Change of value in conversion from "
" %qs to %qs at %L",
gfc_typename (&src->ts), gfc_typename (&result->ts),
&src->where);
did_warn = true;
}
if (!did_warn && warn_conversion_extra && src->ts.kind != kind)
gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs "
"at %L", gfc_typename(&src->ts),
gfc_typename (&result->ts), &src->where);
return result; return result;
} }

View File

@ -3247,55 +3247,6 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform)
} }
} }
/* Warn about type-changing conversions for REAL or COMPLEX constants.
If lvalue and rvalue are mixed REAL and complex, gfc_compare_types
will warn anyway, so there is no need to to so here. */
if (rvalue->expr_type == EXPR_CONSTANT && lvalue->ts.type == rvalue->ts.type
&& (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX))
{
if (lvalue->ts.kind < rvalue->ts.kind && warn_conversion)
{
/* As a special bonus, don't warn about REAL rvalues which are not
changed by the conversion if -Wconversion is specified. */
if (rvalue->ts.type == BT_REAL && mpfr_number_p (rvalue->value.real))
{
/* Calculate the difference between the constant and the rounded
value and check it against zero. */
mpfr_t rv, diff;
gfc_set_model_kind (lvalue->ts.kind);
mpfr_init (rv);
gfc_set_model_kind (rvalue->ts.kind);
mpfr_init (diff);
mpfr_set (rv, rvalue->value.real, GFC_RND_MODE);
mpfr_sub (diff, rv, rvalue->value.real, GFC_RND_MODE);
if (!mpfr_zero_p (diff))
gfc_warning (OPT_Wconversion,
"Change of value in conversion from "
" %qs to %qs at %L", gfc_typename (&rvalue->ts),
gfc_typename (&lvalue->ts), &rvalue->where);
mpfr_clear (rv);
mpfr_clear (diff);
}
else
gfc_warning (OPT_Wconversion,
"Possible change of value in conversion from %qs "
"to %qs at %L", gfc_typename (&rvalue->ts),
gfc_typename (&lvalue->ts), &rvalue->where);
}
else if (warn_conversion_extra && lvalue->ts.kind > rvalue->ts.kind)
{
gfc_warning (OPT_Wconversion_extra,
"Conversion from %qs to %qs at %L",
gfc_typename (&rvalue->ts),
gfc_typename (&lvalue->ts), &rvalue->where);
}
}
if (gfc_compare_types (&lvalue->ts, &rvalue->ts)) if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
return true; return true;

View File

@ -4695,6 +4695,8 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
/* Larger kinds can hold values of smaller kinds without problems. /* Larger kinds can hold values of smaller kinds without problems.
Hence, only warn if target kind is smaller than the source Hence, only warn if target kind is smaller than the source
kind - or if -Wconversion-extra is specified. */ kind - or if -Wconversion-extra is specified. */
if (expr->expr_type != EXPR_CONSTANT)
{
if (warn_conversion && from_ts.kind > ts->kind) if (warn_conversion && from_ts.kind > ts->kind)
gfc_warning_now (OPT_Wconversion, "Possible change of value in " gfc_warning_now (OPT_Wconversion, "Possible change of value in "
"conversion from %s to %s at %L", "conversion from %s to %s at %L",
@ -4705,13 +4707,14 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
"at %L", gfc_typename (&from_ts), "at %L", gfc_typename (&from_ts),
gfc_typename (ts), &expr->where); gfc_typename (ts), &expr->where);
} }
}
else if ((from_ts.type == BT_REAL && ts->type == BT_INTEGER) else if ((from_ts.type == BT_REAL && ts->type == BT_INTEGER)
|| (from_ts.type == BT_COMPLEX && ts->type == BT_INTEGER) || (from_ts.type == BT_COMPLEX && ts->type == BT_INTEGER)
|| (from_ts.type == BT_COMPLEX && ts->type == BT_REAL)) || (from_ts.type == BT_COMPLEX && ts->type == BT_REAL))
{ {
/* Conversion from REAL/COMPLEX to INTEGER or COMPLEX to REAL /* Conversion from REAL/COMPLEX to INTEGER or COMPLEX to REAL
usually comes with a loss of information, regardless of kinds. */ usually comes with a loss of information, regardless of kinds. */
if (warn_conversion) if (warn_conversion && expr->expr_type != EXPR_CONSTANT)
gfc_warning_now (OPT_Wconversion, "Possible change of value in " gfc_warning_now (OPT_Wconversion, "Possible change of value in "
"conversion from %s to %s at %L", "conversion from %s to %s at %L",
gfc_typename (&from_ts), gfc_typename (ts), gfc_typename (&from_ts), gfc_typename (ts),

View File

@ -736,6 +736,58 @@ done:
gfc_internal_error ("gfc_range_check() returned bad value"); gfc_internal_error ("gfc_range_check() returned bad value");
} }
/* Warn about trailing digits which suggest the user added too many
trailing digits, which may cause the appearance of higher pecision
than the kind kan support.
This is done by replacing the rightmost non-zero digit with zero
and comparing with the original value. If these are equal, we
assume the user supplied more digits than intended (or forgot to
convert to the correct kind).
*/
if (warn_conversion_extra)
{
mpfr_t r;
char *c, *p;
bool did_break;
c = strchr (buffer, 'e');
if (c == NULL)
c = buffer + strlen(buffer);
did_break = false;
for (p = c - 1; p >= buffer; p--)
{
if (*p == '.')
continue;
if (*p != '0')
{
*p = '0';
did_break = true;
break;
}
}
if (did_break)
{
mpfr_init (r);
mpfr_set_str (r, buffer, 10, GFC_RND_MODE);
if (negate)
mpfr_neg (r, r, GFC_RND_MODE);
mpfr_sub (r, r, e->value.real, GFC_RND_MODE);
if (mpfr_cmp_ui (r, 0) == 0)
gfc_warning (OPT_Wconversion_extra, "Non-significant digits "
"in %qs number at %C, maybe incorrect KIND",
gfc_typename (&e->ts));
mpfr_clear (r);
}
}
*result = e; *result = e;
return MATCH_YES; return MATCH_YES;

View File

@ -1,3 +1,14 @@
2015-06-06 Thomas Koenig <tkoenig@netcologne.de>
PR fortran/47359
* gfortran.dg/array_constructor_type_17.f03: Adjust error message.
* gfortran.dg/warn_conversion.f90: Add warning for change in value
for assignment.
* gfortran.dg/warn_conversion_3.f90: Add warnings.
* gfortran.dg/warn_conversion_5.f90: New test.
* gfortran.dg/warn_conversion_6.f90: New test.
* gfortran.dg/warn_conversion_7.f90: New test.
2015-06-05 Steven G. Kargl <kargl@gcc.gnu.org> 2015-06-05 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/66347 PR fortran/66347

View File

@ -8,5 +8,5 @@ PROGRAM test
IMPLICIT NONE IMPLICIT NONE
INTEGER(KIND=4) :: arr(1) INTEGER(KIND=4) :: arr(1)
arr = (/ INTEGER(KIND=4) :: HUGE(0_8) /) ! { dg-warning "conversion from" } arr = (/ INTEGER(KIND=4) :: HUGE(0_8) /) ! { dg-warning "Conversion" }
END PROGRAM test END PROGRAM test

View File

@ -18,7 +18,7 @@ SUBROUTINE pr27866c4
integer(kind=4) :: i4 integer(kind=4) :: i4
i4 = 2.3 ! { dg-warning "conversion" } i4 = 2.3 ! { dg-warning "conversion" }
i1 = 500 ! { dg-error "overflow" } i1 = 500 ! { dg-error "overflow" }
a = 2**26-1 ! assignment INTEGER(4) to REAL(4) - no warning a = 2**26-1 ! { dg-warning "Change of value in conversion" }
b = 1d999 ! { dg-error "overflow" } b = 1d999 ! { dg-error "overflow" }
a = i4 ! assignment INTEGER(4) to REAL(4) - no warning a = i4 ! assignment INTEGER(4) to REAL(4) - no warning

View File

@ -7,8 +7,8 @@ program main
complex(8), parameter :: z = cmplx (0.5, 0.5) ! { dg-warning "Conversion" } complex(8), parameter :: z = cmplx (0.5, 0.5) ! { dg-warning "Conversion" }
real :: r1, r2 real :: r1, r2
r1 = 2.3d0 ! { dg-warning "Change of value in conversion" } r1 = 2.3d0 ! { dg-warning "Change of value in conversion" }
r2 = 2.5d0 ! No warning because the value does not change r2 = 2.5d0 ! { dg-warning "Conversion" }
d1 = .13 ! { dg-warning "Conversion" } d1 = .13 ! { dg-warning "Conversion" }
d2 = .13d0 d2 = .13d0
d1 = z ! { dg-warning "change of value in conversion" } d1 = z ! { dg-warning "Non-zero imaginary part" }
end program main end program main

View File

@ -0,0 +1,37 @@
! { dg-do compile }
! { dg-options "-Wconversion" }
! PR 47359 - additional warnings for conversions.
program main
implicit none
complex(kind=4) :: c4
complex(kind=8) :: c8
real(kind=4) :: r4
real(kind=8) :: r8
complex(kind=4), parameter :: c4p = (1.0, -4.)
complex, parameter :: c8w = (1.0_8, -4.2_8) ! { dg-warning "Change of value in conversion" }
complex (kind=8), parameter :: c8p = (1.0_8, -4.2_8)
integer :: i
c4 = c8p ! { dg-warning "Change of value in conversion" }
c4 = 2**26 + 1 ! { dg-warning "Change of value in conversion" }
c4 = 1.3d0 ! { dg-warning "Change of value in conversion" }
c4 = c8p ! { dg-warning "Change of value in conversion" }
c4 = (1.2, 1000000001) ! { dg-warning "Change of value in conversion" }
r4 = (2**26 + 1) * 2.3 ! { dg-warning "Change of value in conversion" }
r4 = 2.4d0 ! { dg-warning "Change of value" }
r4 = c4p ! { dg-warning "Non-zero imaginary part" }
r4 = r4 + 2.3d0 ! { dg-warning "Possible change of value in conversion" }
r8 = 2_8**62 - 1_8 ! { dg-warning "Change of value in conversion" }
i = c4p ! { dg-warning "Non-zero imaginary part" }
i = 42 + 1.3 ! { dg-warning "Change of value in conversion" }
i = (1.2, 0.) ! { dg-warning "Change of value in conversion" }
c4 = 1.2 ! no warning
c4 = -3.25d0 ! no warning
c4 = -42 ! no warning
c8 = 2**26 + 1 ! no warning
i = 22. ! no warning
i = (35., 0.) ! no warning
r4 = 2.5d0 ! no warning
r4 = 235 ! no warning
r8 = 2.3 ! no warning
end program main

View File

@ -0,0 +1,21 @@
! { dg-do compile }
! { dg-options "-Wconversion -Wconversion-extra" }
! PR 47359 - additional warnings for conversions.
program main
implicit none
real(kind=8) :: a,b
complex(kind=8) :: c
integer :: i
real(kind=4) :: r
a = 0.13 ! { dg-warning "Conversion" }
print *,0.1_8 ** 0.2 ! { dg-warning "Conversion" }
b = a/0.13 ! { dg-warning "Conversion" }
i = 12345. ! { dg-warning "Conversion" }
i = (1., 23.) ! { dg-warning "Non-zero imaginary part" }
r = (1., 23.) ! { dg-warning "Non-zero imaginary part" }
b = 0.& ! { dg-warning "Possible change of value" }
&5_8*c ! { dg-warning "Conversion" }
c = 0.3 ! { dg-warning "Conversion" }
a = 0.5 ! { dg-warning "Conversion" }
end program main

View File

@ -0,0 +1,7 @@
! { dg-do compile }
! { dg-options "-Wconversion-extra -Wconversion" }
program main
implicit none
double precision, parameter :: pi = & ! { dg-warning "Conversion" }
& 3.1415829535897932 ! { dg-warning "Non-significant digits" }
end program main