public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: HAO CHEN GUI <guihaoc@linux.ibm.com>
To: gcc-patches <gcc-patches@gcc.gnu.org>, fortran <fortran@gcc.gnu.org>
Cc: Segher Boessenkool <segher@kernel.crashing.org>,
	David <dje.gcc@gmail.com>, "Kewen.Lin" <linkw@linux.ibm.com>,
	Peter Bergner <bergner@linux.ibm.com>,
	Tobias Burnus <tobias@codesourcery.com>
Subject: [PATCHv4, gfortran] Escalate failure when Hollerith constant to real conversion fails [PR103628]
Date: Tue, 21 Mar 2023 14:29:50 +0800	[thread overview]
Message-ID: <fe6ba084-3b72-7ae9-1cb3-9a3ad889eaf8@linux.ibm.com> (raw)

Hi,
  I refined the patch according to reviewer's advice. The main change is to
check if buffer_p is set and buffered error exists. Also two regtests are
fixed by catching the new error.

  I sent out the revised one for review due to my limited knowledge on
Fortran front end.

  The patch escalates the failure when Hollerith constant to real conversion
fails in native_interpret_expr. It finally reports an "Cannot simplify
expression" error in do_simplify method.

  The patch for pr95450 added a verification for decoding/encoding checking
in native_interpret_expr. native_interpret_expr may fail on real type
conversion and returns a NULL tree then. But upper layer calls don't handle
the failure so that an ICE is reported when the verification fails.

  IBM long double is an example. It doesn't have a unique memory presentation
for some real values. So it may not pass the verification. The new test
case shows the problem.

  errorcount is used to check if an error is already reported or not when
getting a bad expr. Buffered errors need to be excluded as they don't
increase error count either.

  The patch passed regression test on Power and x86 linux platforms.

Thanks
Gui Haochen

ChangeLog
2023-03-21  Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	PR target/103628
	* fortran/target-memory.cc (gfc_interpret_float): Return FAIL when
	native_interpret_expr gets a NULL tree.
	* fortran/arith.cc (gfc_hollerith2real): Return NULL when
	gfc_interpret_float fails.
	* fortran/error.cc (gfc_buffered_p): Define.
	* fortran/gfortran.h (gfc_buffered_p): Declare.
	* fortran/intrinsic.cc: Add diagnostic.h to include list.
	(do_simplify): Save errorcount and check it at finish.  Report a
	"Cannot simplify expression" error on a bad result if error count
	doesn't change and no other errors buffered.

gcc/testsuite/
	PR target/103628
	* gfortran.dg/assumed_size_refs_2.f90: Catch "Cannot simplify
	expression" error.
	* gfortran.dg/unpack_field_1.f90: Likewise.
	* gfortran.dg/pr103628.f90: New.

Co-Authored-By: Tobias Burnus <tobias@codesourcery.com>


patch.diff
diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index c0d12cfad9d..d3d38c7eb6a 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -2752,10 +2752,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 214fb78ba7b..872d42e731e 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 219ef8c7612..edfe11796a6 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3328,6 +3328,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 e89131f5a71..2572b7a3448 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 7ce7d736629..0c47aa6b842 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 8eb708d4989..632b1085548 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 00000000000..255d5bdd73e
--- /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 ca3cfbd2bd4..1951484f147 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 }

             reply	other threads:[~2023-03-21  6:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-21  6:29 HAO CHEN GUI [this message]
2023-03-21 10:09 ` Tobias Burnus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fe6ba084-3b72-7ae9-1cb3-9a3ad889eaf8@linux.ibm.com \
    --to=guihaoc@linux.ibm.com \
    --cc=bergner@linux.ibm.com \
    --cc=dje.gcc@gmail.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=linkw@linux.ibm.com \
    --cc=segher@kernel.crashing.org \
    --cc=tobias@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).