public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR fortran/58027,60993 -- BOZ in array constructor initialization expression
@ 2015-11-16  2:22 Steve Kargl
  2015-11-16  5:48 ` Paul Richard Thomas
  0 siblings, 1 reply; 2+ messages in thread
From: Steve Kargl @ 2015-11-16  2:22 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1665 bytes --]

First, thanks to Dominiq for prodding me into looking at PR 58027.

This was a fun ICE to track down!

Most users have no idea what the Fortran standard requires for
the parsing of a BOZ.  Consider the line of code

  integer, parameter :: i(1) = (/ z'ff800000' /)

The naive user wants to assign a BOZ interpreted as a 32-bit entity
to i(1) in an array constructor.  Ignoring the fact that a BOZ 
can't be used here, the BOZ is converted to an integer with the
widest decimal exponential range.  On all(?) targets this is at
least a 64-bit integer (known as INTEGER(8)).  To do the assignment
gfortan inserts a __convert_i8_i4(), but it does so after any
checking for an initialization expression.  So, when gfortran
finally gets around to calling gfc_conv_array_initializer() to
translates into tree-ssa form, gfc_conv_array_initializer() is not
expecting a function and dies with an ICE. 

The fix is affected by calling gfc_check_init_expr() under
appropriate conditions.  Because the __convert_* functions
are sort of psuedo-intrinsic procedures, a check for an intrinsic
procedure needs to be circumvented.

Anyway, the patch has been built and tested on i386-*-freebsd
and x86_64-*-freebsd.  OK to commit?

2015-11-15  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/58027
	PR fortran/60993
	* expr.c (gfc_check_init_expr): Prevent a redundant check when a
	__convert_* function was inserted into an array constructor.
	(gfc_check_assign_symbol): Check for an initialization expression
	when a __convert_* was inserted.

2015-11-15  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/58027
	PR fortran/60993
	* gfortran.dg/pr58027.f90: New test.

-- 
Steve

[-- Attachment #2: pr58027.diff --]
[-- Type: text/x-diff, Size: 2508 bytes --]

Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 230397)
+++ gcc/fortran/expr.c	(working copy)
@@ -2471,7 +2471,8 @@ gfc_check_init_expr (gfc_expr *e)
       t = false;
 
       {
-	gfc_intrinsic_sym* isym;
+	bool conversion;
+	gfc_intrinsic_sym* isym = NULL;
 	gfc_symbol* sym = e->symtree->n.sym;
 
 	/* Simplify here the intrinsics from the IEEE_ARITHMETIC and
@@ -2490,8 +2491,14 @@ gfc_check_init_expr (gfc_expr *e)
 	      }
 	  }
 
-	if (!gfc_is_intrinsic (sym, 0, e->where)
-	    || (m = gfc_intrinsic_func_interface (e, 0)) != MATCH_YES)
+	/* If a conversion function, e.g., __convert_i8_i4, was inserted
+	   into an array constructor, we need to skip the error check here.
+           Conversion errors are  caught below in scalarize_intrinsic_call.  */
+	conversion = e->value.function.isym
+		   && (e->value.function.isym->conversion == 1);
+
+	if (!conversion && (!gfc_is_intrinsic (sym, 0, e->where)
+	    || (m = gfc_intrinsic_func_interface (e, 0)) != MATCH_YES))
 	  {
 	    gfc_error ("Function %qs in initialization expression at %L "
 		       "must be an intrinsic function",
@@ -2518,7 +2525,7 @@ gfc_check_init_expr (gfc_expr *e)
 	   array argument.  */
 	isym = gfc_find_function (e->symtree->n.sym->name);
 	if (isym && isym->elemental
-	    && (t = scalarize_intrinsic_call(e)))
+	    && (t = scalarize_intrinsic_call (e)))
 	  break;
       }
 
@@ -3844,7 +3851,17 @@ gfc_check_assign_symbol (gfc_symbol *sym
   if (pointer || proc_pointer)
     r = gfc_check_pointer_assign (&lvalue, rvalue);
   else
-    r = gfc_check_assign (&lvalue, rvalue, 1);
+    {
+      /* If a conversion function, e.g., __convert_i8_i4, was inserted
+	 into an array constructor, we should check if it can be reduced
+	 as an initialization expression.  */
+      if (rvalue->expr_type == EXPR_FUNCTION
+	  && rvalue->value.function.isym
+	  && (rvalue->value.function.isym->conversion == 1))
+	gfc_check_init_expr (rvalue);
+
+      r = gfc_check_assign (&lvalue, rvalue, 1);
+    }
 
   free (lvalue.symtree);
   free (lvalue.ref);
Index: gcc/testsuite/gfortran.dg/pr58027.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr58027.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr58027.f90	(working copy)
@@ -0,0 +1,5 @@
+! { dg-do compile }
+! PR fortran/58027
+integer, parameter :: i(1)=(/z'ff800000'/) ! { dg-error "overflow converting" }
+print *, isclass
+end

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] PR fortran/58027,60993 -- BOZ in array constructor initialization expression
  2015-11-16  2:22 [PATCH] PR fortran/58027,60993 -- BOZ in array constructor initialization expression Steve Kargl
@ 2015-11-16  5:48 ` Paul Richard Thomas
  0 siblings, 0 replies; 2+ messages in thread
From: Paul Richard Thomas @ 2015-11-16  5:48 UTC (permalink / raw)
  To: Steve Kargl; +Cc: fortran, gcc-patches

Dear Steve,

OK for trunk.

Some of the code around the patch brings back fond memories;
especially the "scalarization"!

Thanks for the patch.

Paul

On 16 November 2015 at 03:22, Steve Kargl
<sgk@troutmask.apl.washington.edu> wrote:
> First, thanks to Dominiq for prodding me into looking at PR 58027.
>
> This was a fun ICE to track down!
>
> Most users have no idea what the Fortran standard requires for
> the parsing of a BOZ.  Consider the line of code
>
>   integer, parameter :: i(1) = (/ z'ff800000' /)
>
> The naive user wants to assign a BOZ interpreted as a 32-bit entity
> to i(1) in an array constructor.  Ignoring the fact that a BOZ
> can't be used here, the BOZ is converted to an integer with the
> widest decimal exponential range.  On all(?) targets this is at
> least a 64-bit integer (known as INTEGER(8)).  To do the assignment
> gfortan inserts a __convert_i8_i4(), but it does so after any
> checking for an initialization expression.  So, when gfortran
> finally gets around to calling gfc_conv_array_initializer() to
> translates into tree-ssa form, gfc_conv_array_initializer() is not
> expecting a function and dies with an ICE.
>
> The fix is affected by calling gfc_check_init_expr() under
> appropriate conditions.  Because the __convert_* functions
> are sort of psuedo-intrinsic procedures, a check for an intrinsic
> procedure needs to be circumvented.
>
> Anyway, the patch has been built and tested on i386-*-freebsd
> and x86_64-*-freebsd.  OK to commit?
>
> 2015-11-15  Steven G. Kargl  <kargl@gcc.gnu.org>
>
>         PR fortran/58027
>         PR fortran/60993
>         * expr.c (gfc_check_init_expr): Prevent a redundant check when a
>         __convert_* function was inserted into an array constructor.
>         (gfc_check_assign_symbol): Check for an initialization expression
>         when a __convert_* was inserted.
>
> 2015-11-15  Steven G. Kargl  <kargl@gcc.gnu.org>
>
>         PR fortran/58027
>         PR fortran/60993
>         * gfortran.dg/pr58027.f90: New test.
>
> --
> Steve



-- 
Outside of a dog, a book is a man's best friend. Inside of a dog it's
too dark to read.

Groucho Marx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-11-16  5:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-16  2:22 [PATCH] PR fortran/58027,60993 -- BOZ in array constructor initialization expression Steve Kargl
2015-11-16  5:48 ` Paul Richard Thomas

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).