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