diff mbox

PR fortran/78618 -- RANK() should not ICE

Message ID 20161202013354.GA42106@troutmask.apl.washington.edu
State New
Headers show

Commit Message

Steve Kargl Dec. 2, 2016, 1:33 a.m. UTC
The attached patch fixes an ICE, a nearby whitespace issue, and
removed the ATTRIBUTE_UNUSED tag.  THe change has passed regression
testing on x86_64-*-freebsd.  Ok to commit?

2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/78618
	* check.c (gfc_check_rank): Remove ATTRIBUTE_UNUSED.  Fix whitespace.
	Fix ICE where a NULL pointer is dereferenced.
	* simplify.c (gfc_convert_char_constant):  Do not buffer error.

2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/78618
	* gfortran.dg/char_conversion.f90: New test.

Comments

Janus Weil Dec. 2, 2016, 3:47 p.m. UTC | #1
Hi Steve,

2016-12-02 2:33 GMT+01:00 Steve Kargl <sgk@troutmask.apl.washington.edu>:
> The attached patch fixes an ICE, a nearby whitespace issue, and
> removed the ATTRIBUTE_UNUSED tag.  THe change has passed regression
> testing on x86_64-*-freebsd.  Ok to commit?

huh, I don't really understand why the argument of RANK is detected to
be an EXPR_FUNCTION for the test case at hand. Shouldn't it rather be
an EXPR_CONSTANT?

Some debugging in gfc_check_rank shows that a->symtree->n.sym indeed
is the symbol "c" (as expected), but that clearly is not a function,
so it seems to me that the actual bug here is that a->expr_type is set
incorrectly ...?

Cheers,
Janus




> 2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>
>
>         PR fortran/78618
>         * check.c (gfc_check_rank): Remove ATTRIBUTE_UNUSED.  Fix whitespace.
>         Fix ICE where a NULL pointer is dereferenced.
>         * simplify.c (gfc_convert_char_constant):  Do not buffer error.
>
> 2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>
>
>         PR fortran/78618
>         * gfortran.dg/char_conversion.f90: New test.
>
> --
> Steve
Steve Kargl Dec. 2, 2016, 4:30 p.m. UTC | #2
On Fri, Dec 02, 2016 at 04:47:19PM +0100, Janus Weil wrote:
> Hi Steve,
> 
> 2016-12-02 2:33 GMT+01:00 Steve Kargl <sgk@troutmask.apl.washington.edu>:
> > The attached patch fixes an ICE, a nearby whitespace issue, and
> > removed the ATTRIBUTE_UNUSED tag.  THe change has passed regression
> > testing on x86_64-*-freebsd.  Ok to commit?
> 
> huh, I don't really understand why the argument of RANK is detected to
> be an EXPR_FUNCTION for the test case at hand. Shouldn't it rather be
> an EXPR_CONSTANT?
> 
> Some debugging in gfc_check_rank shows that a->symtree->n.sym indeed
> is the symbol "c" (as expected), but that clearly is not a function,
> so it seems to me that the actual bug here is that a->expr_type is set
> incorrectly ...?
> 

I found that it is the function __convert_s4_s1.   Namely,  we have

character, parameter :: c = char(256,4)
print *, rank(c)

c is kind=1 and char(256,4) is kind 4.  so, we end up with

print *, rank(__convert_s4_s1(...))

As __convert_s4_s1() has neither isym nor esym set, you get a problem.
Andreas Schwab Dec. 3, 2016, 4:58 p.m. UTC | #3
On Dez 01 2016, Steve Kargl <sgk@troutmask.apl.washington.edu> wrote:

> 	PR fortran/78618
> 	* gfortran.dg/char_conversion.f90: New test.

That test still crashes the compiler on m68k:

/daten/aranym/gcc/gcc-20161203/gcc/testsuite/gfortran.dg/char_conversion.f90:8:30: Error: Character '\u0100' in string at (1) cannot be converted into character kind 1
f951: internal compiler error: Segmentation fault
0xb40a7f crash_signal
        ../../gcc/toplev.c:333
0x58dd52 gfc_is_constant_expr(gfc_expr*)
        ../../gcc/fortran/expr.c:899
0x5feb90 resolve_fl_procedure
        ../../gcc/fortran/resolve.c:12013
0x5feb90 resolve_symbol
        ../../gcc/fortran/resolve.c:14721
0x616e73 do_traverse_symtree
        ../../gcc/fortran/symbol.c:3994
0x6007d4 resolve_types
        ../../gcc/fortran/resolve.c:15948
0x5fc3e4 gfc_resolve
        ../../gcc/fortran/resolve.c:16061
0x5e70b2 resolve_all_program_units
        ../../gcc/fortran/parse.c:5977
0x5e70b2 gfc_parse_file()
        ../../gcc/fortran/parse.c:6224
0x629da2 gfc_be_parse_file
        ../../gcc/fortran/f95-lang.c:202

Andreas.
Steve Kargl Dec. 3, 2016, 5:10 p.m. UTC | #4
On Sat, Dec 03, 2016 at 05:58:02PM +0100, Andreas Schwab wrote:
> On Dez 01 2016, Steve Kargl <sgk@troutmask.apl.washington.edu> wrote:
> 
> > 	PR fortran/78618
> > 	* gfortran.dg/char_conversion.f90: New test.
> 
> That test still crashes the compiler on m68k:
> 
> 0xb40a7f crash_signal
>         ../../gcc/toplev.c:333
> 0x58dd52 gfc_is_constant_expr(gfc_expr*)
>         ../../gcc/fortran/expr.c:899
> 0x5feb90 resolve_fl_procedure
>         ../../gcc/fortran/resolve.c:12013

Yes, we know.  I've reopen the PR; see audit trail.
It seems to be a used-after-freed issue, but I've
been unable to track down the issue.
diff mbox

Patch

Index: gcc/fortran/check.c
===================================================================
--- gcc/fortran/check.c	(revision 243142)
+++ gcc/fortran/check.c	(working copy)
@@ -3667,7 +3667,7 @@  gfc_check_range (gfc_expr *x)
 
 
 bool
-gfc_check_rank (gfc_expr *a ATTRIBUTE_UNUSED)
+gfc_check_rank (gfc_expr *a)
 {
   /* Any data object is allowed; a "data object" is a "constant (4.1.3),
      variable (6), or subobject of a constant (2.4.3.2.3)" (F2008, 1.3.45).  */
@@ -3676,9 +3676,16 @@  gfc_check_rank (gfc_expr *a ATTRIBUTE_UN
 
   /* Functions returning pointers are regarded as variable, cf. F2008, R602.  */
   if (a->expr_type == EXPR_FUNCTION)
-    is_variable = a->value.function.esym
-		  ? a->value.function.esym->result->attr.pointer
-		  : a->symtree->n.sym->result->attr.pointer;
+    {
+      if (a->value.function.esym)
+	is_variable = a->value.function.esym->result->attr.pointer;
+      else if (a->symtree->n.sym->result)
+	is_variable = a->symtree->n.sym->result->attr.pointer;
+      else if (a->symtree->n.sym->value)
+	is_variable = true;
+      else
+	gfc_internal_error ("gfc_check_rank(): invalid function result");
+    }
 
   if (a->expr_type == EXPR_OP || a->expr_type == EXPR_NULL
       || a->expr_type == EXPR_COMPCALL|| a->expr_type == EXPR_PPC
Index: gcc/fortran/simplify.c
===================================================================
--- gcc/fortran/simplify.c	(revision 243142)
+++ gcc/fortran/simplify.c	(working copy)
@@ -7148,7 +7148,7 @@  gfc_convert_char_constant (gfc_expr *e, 
 	if (!gfc_check_character_range (result->value.character.string[i],
 					kind))
 	  {
-	    gfc_error ("Character %qs in string at %L cannot be converted "
+	    gfc_error_now ("Character %qs in string at %L cannot be converted "
 		       "into character kind %d",
 		       gfc_print_wide_char (result->value.character.string[i]),
 		       &e->where, kind);
Index: gcc/testsuite/gfortran.dg/char_conversion.f90
===================================================================
--- gcc/testsuite/gfortran.dg/char_conversion.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/char_conversion.f90	(working copy)
@@ -0,0 +1,6 @@ 
+! { dg-do compile }
+! PR fortran/78618
+program p
+   character, parameter :: c = char(256,4) ! { dg-error "cannot be converted" }
+   if (rank(c) /= 0) call abort
+end