diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index 37aeaf1b186ff75984f025229b7c2c10be1ea970..ddf9874671cd25cb8dd3e248a24cafcd1eefa8e4 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -2753,10 +2753,12 @@ gfc_hollerith2real (gfc_expr *src, int kind) result = gfc_get_constant_expr (BT_REAL, kind, &src->where); hollerith2representation (result, src); - gfc_interpret_float (kind, (unsigned char *) result->representation.string, - result->representation.length, result->value.real); - - return result; + if (gfc_interpret_float (kind, + (unsigned char *) result->representation.string, + result->representation.length, result->value.real)) + return result; + else + return NULL; } /* Convert character to real. The constant will be padded or truncated. */ diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc index 05d3a0e1f5a67db3d3fe47587c313918d094c9df..6cae6726f91c5fd0bbffc89ffbc48e1b074d202a 100644 --- a/gcc/fortran/error.cc +++ b/gcc/fortran/error.cc @@ -49,6 +49,13 @@ static gfc_error_buffer error_buffer; static output_buffer *pp_error_buffer, *pp_warning_buffer; static int warningcount_buffered, werrorcount_buffered; +/* Return buffered_p. */ +bool +gfc_buffered_p (void) +{ + return buffered_p; +} + /* Return true if there output_buffer is empty. */ static bool diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 9bab2c40ead3f5394213636f60823346701f6aa2..130d5d7e5b743a322ef0111e8b2084004304b963 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3331,6 +3331,7 @@ void gfc_internal_error (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_GCC_GFC void gfc_clear_error (void); bool gfc_error_check (void); bool gfc_error_flag_test (void); +bool gfc_buffered_p (void); notification gfc_notification_std (int); bool gfc_notify_std (int, const char *, ...) ATTRIBUTE_GCC_GFC(2,3); diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc index 64821c84543df70d793a8f63d713d9416911885f..1a26b7a571ff5203eb9965f11c256c0085224fa3 100644 --- a/gcc/fortran/intrinsic.cc +++ b/gcc/fortran/intrinsic.cc @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "options.h" #include "gfortran.h" #include "intrinsic.h" +#include "diagnostic.h" /* For errorcount. */ /* Namespace to hold the resolved symbols for intrinsic subroutines. */ static gfc_namespace *gfc_intrinsic_namespace; @@ -4620,6 +4621,7 @@ do_simplify (gfc_intrinsic_sym *specific, gfc_expr *e) { gfc_expr *result, *a1, *a2, *a3, *a4, *a5, *a6; gfc_actual_arglist *arg; + int old_errorcount = errorcount; /* Max and min require special handling due to the variable number of args. */ @@ -4708,7 +4710,12 @@ do_simplify (gfc_intrinsic_sym *specific, gfc_expr *e) finish: if (result == &gfc_bad_expr) - return false; + { + if (errorcount == old_errorcount + && (!gfc_buffered_p () || !gfc_error_flag_test ())) + gfc_error ("Cannot simplify expression at %L", &e->where); + return false; + } if (result == NULL) resolve_intrinsic (specific, e); /* Must call at run-time */ diff --git a/gcc/fortran/target-memory.cc b/gcc/fortran/target-memory.cc index 05b82558672df0fc3c11afeaf583b1e1f6b20cee..edc30bddb52940e67de719401567339cfa8c6c28 100644 --- a/gcc/fortran/target-memory.cc +++ b/gcc/fortran/target-memory.cc @@ -416,11 +416,14 @@ gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size, mpfr_t real) { gfc_set_model_kind (kind); - mpfr_init (real); - gfc_conv_tree_to_mpfr (real, - native_interpret_expr (gfc_get_real_type (kind), - buffer, buffer_size)); + tree source = native_interpret_expr (gfc_get_real_type (kind), buffer, + buffer_size); + if (!source) + return 0; + + mpfr_init (real); + gfc_conv_tree_to_mpfr (real, source); return size_float (kind); } diff --git a/gcc/testsuite/gfortran.dg/assumed_size_refs_2.f90 b/gcc/testsuite/gfortran.dg/assumed_size_refs_2.f90 index 8eb708d4989804406a8be36ad298081ac8af4358..632b1085548bb977e2b9b3be0ba958ae7b805a94 100644 --- a/gcc/testsuite/gfortran.dg/assumed_size_refs_2.f90 +++ b/gcc/testsuite/gfortran.dg/assumed_size_refs_2.f90 @@ -42,3 +42,5 @@ contains end subroutine foo end program assumed_size_test_2 + +! { dg-error "Cannot simplify expression" " " { target *-*-* } 29 } diff --git a/gcc/testsuite/gfortran.dg/pr103628.f90 b/gcc/testsuite/gfortran.dg/pr103628.f90 new file mode 100644 index 0000000000000000000000000000000000000000..255d5bdd73e399f8b20160b414a6f339cabd577b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103628.f90 @@ -0,0 +1,14 @@ +! { dg-do compile { target powerpc*-*-* } } +! { dg-options "-O2 -mabi=ibmlongdouble" } + +! Test to ensure that it reports an "Cannot simplify expression" error +! instead of throwing an ICE when the memory represent of the HOLLERITH +! string is not unique with ibm long double encoding. + +program main + integer, parameter :: k = 16 + real(kind = k):: b = 4h1234 +end program main + +! { dg-warning "Conversion from HOLLERITH" "warning" { target powerpc*-*-* } 10 } +! { dg-error "Cannot simplify expression" "error" { target powerpc*-*-* } 10 } diff --git a/gcc/testsuite/gfortran.dg/unpack_field_1.f90 b/gcc/testsuite/gfortran.dg/unpack_field_1.f90 index ca3cfbd2bd45b39f4ce8612922b67ffbb06b3763..1951484f14743f03323bc6200e88a16b4830a386 100644 --- a/gcc/testsuite/gfortran.dg/unpack_field_1.f90 +++ b/gcc/testsuite/gfortran.dg/unpack_field_1.f90 @@ -13,3 +13,5 @@ program p print *, unpack(a,mask,d) ! OK print *, unpack(a,mask,3) ! OK end + +! { dg-error "Cannot simplify expression" " " { target *-*-* } 12 }