Bug 46459 - ICE (segfault): Invalid read in compare_actual_formal [error recovery]
Summary: ICE (segfault): Invalid read in compare_actual_formal [error recovery]
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 7.0
Assignee: janus
URL:
Keywords: ice-on-invalid-code, patch
Depends on:
Blocks:
 
Reported: 2010-11-12 23:52 UTC by Tobias Burnus
Modified: 2016-11-09 20:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-03-01 15:53:23


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-11-12 23:52:22 UTC
The following program segfaults after printing the diagnostic:

call sub(1)
        1
Error: Dummy argument 'j' of procedure 'sub' at (1) has an attribute that requires an explicit interface for this procedure


subroutine sub(j)
  integer, volatile :: j
end subroutine sub

call sub(1)
end


Valgrind shows:

 Invalid read of size 8
    at 0x4E180F: compare_actual_formal (interface.c:2270)
    by 0x4E332D: gfc_procedure_use (interface.c:2678)
    by 0x522834: resolve_global_procedure (resolve.c:2195)
    by 0x52A634: resolve_call (resolve.c:3550)
Comment 1 Mikael Morin 2011-02-18 21:13:11 UTC
low hanging fruit:

diff --git a/interface.c b/interface.c
index 1e5df61..32c8b6e 100644
--- a/interface.c
+++ b/interface.c
@@ -2292,6 +2292,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal
         shape array, if the dummy argument has the VOLATILE attribute.  */
 
       if (f->sym->attr.volatile_
+         && a->expr->expr_type == EXPR_VARIABLE
          && a->expr->symtree->n.sym->as
          && a->expr->symtree->n.sym->as->type == AS_ASSUMED_SHAPE
          && !(f->sym->as && f->sym->as->type == AS_ASSUMED_SHAPE))
@@ -2321,6 +2322,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal
         dummy argument has the VOLATILE attribute.  */
 
       if (f->sym->attr.volatile_
+         && a->expr->expr_type == EXPR_VARIABLE
          && a->expr->symtree->n.sym->attr.pointer
          && a->expr->symtree->n.sym->as
          && !(f->sym->as
Comment 2 Mikael Morin 2011-02-18 21:16:03 UTC
By the way the conditions should not test against
 a->expr->symtree->n.sym->as->type
as it does not support derived type components.
Comment 3 Dominique d'Humieres 2011-03-01 15:53:23 UTC
The patch in comment #1 fixes the ICE, but I am not sure to understand comment #2.
Comment 4 Mikael Morin 2011-03-04 23:37:00 UTC
(In reply to comment #3)
> I am not sure to understand comment #2.
You're right, assumed shapes are only for procedure arguments. For derived types components the syntax is the same, but the word is deferred shape.
Then the conditions are fine and comment #2 is irrelevant.
Comment 5 Mikael Morin 2013-06-14 20:36:04 UTC
The initial test doesn't lead to a segfault any more.

It is now rejected with:
comment_0.f90:7.8:

call sub(1)
        1
Error: Explicit interface required for 'sub' at (1): volatile argument


However, the following variant is also rejected with the same error:

 call sub(1)
contains
  subroutine sub(j)
   integer, volatile :: j
  end subroutine sub
end
Comment 6 Harald Anlauf 2016-02-05 21:27:48 UTC
(In reply to Mikael Morin from comment #5)
> The initial test doesn't lead to a segfault any more.
> 
> It is now rejected with:
> comment_0.f90:7.8:
> 
> call sub(1)
>         1
> Error: Explicit interface required for 'sub' at (1): volatile argument
> 
> 
> However, the following variant is also rejected with the same error:
> 
>  call sub(1)
> contains
>   subroutine sub(j)
>    integer, volatile :: j
>   end subroutine sub
> end

With current trunk I get for this testcase:

f951: internal compiler error: Segmentation fault
0x884c5d0 crash_signal
        ../../trunk/gcc/toplev.c:335
0x8247bb7 compare_actual_formal
        ../../trunk/gcc/fortran/interface.c:2972
0x8248f02 gfc_procedure_use(gfc_symbol*, gfc_actual_arglist**, locus*)
        ../../trunk/gcc/fortran/interface.c:3441
0x82a0753 resolve_specific_s0
        ../../trunk/gcc/fortran/resolve.c:3282
0x82a0753 resolve_specific_s
        ../../trunk/gcc/fortran/resolve.c:3302
0x82a0753 resolve_call
        ../../trunk/gcc/fortran/resolve.c:3456
0x82a8b14 gfc_resolve_code(gfc_code*, gfc_namespace*)
        ../../trunk/gcc/fortran/resolve.c:10613
0x82ab342 resolve_codes
        ../../trunk/gcc/fortran/resolve.c:15529
0x829a1aa gfc_resolve
        ../../trunk/gcc/fortran/resolve.c:15563
0x829a1aa gfc_resolve
        ../../trunk/gcc/fortran/resolve.c:15543
0x828ec38 resolve_all_program_units
        ../../trunk/gcc/fortran/parse.c:5551
0x828ec38 gfc_parse_file()
        ../../trunk/gcc/fortran/parse.c:5803
0x82d2a55 gfc_be_parse_file
        ../../trunk/gcc/fortran/f95-lang.c:201
Comment 7 Harald Anlauf 2016-02-29 21:54:06 UTC
The patch of comment #1 (adjusted to current trunk) regtests cleanly
for me.

(In reply to Mikael Morin from comment #5)
> The initial test doesn't lead to a segfault any more.
> 
> It is now rejected with:
> comment_0.f90:7.8:
> 
> call sub(1)
>         1
> Error: Explicit interface required for 'sub' at (1): volatile argument

I think this is correct, see below (*).

> 
> However, the following variant is also rejected with the same error:
> 
>  call sub(1)
> contains
>   subroutine sub(j)
>    integer, volatile :: j
>   end subroutine sub
> end

I do not get any error for this case, which is correct.

(*) The requirement for an explicit interface is described in F2008,
section 12.4.2.2 (2a), and is already properly handled by
gfc_explicit_interface_required().

I threw this testcase at the Cray compiler:

% cat pr46459.f90
  call sub (1)
contains
  subroutine sub (j)
    integer, volatile :: j
  end subroutine sub
end

subroutine sub1 ()
  call sub2 (1)         ! { dg-error "Explicit interface required" }
end subroutine sub1
subroutine sub2 (j)
  integer, volatile :: j
end subroutine sub2

subroutine sub3 ()
  interface
     subroutine sub2 (j)
       integer, volatile :: j
     end subroutine sub2
  end interface
  call sub2 (1)
end subroutine sub3


% ftn pr46459.f90   

subroutine sub2 (j)
           ^        
ftn-954 crayftn: ERROR SUB2, File = pr46459.f90, Line = 11, Column = 12 
  Procedure "SUB2", referenced at line 9 (pr46459.f90) must have an explicit interface because one or more arguments have the VOLATILE attribute.


This would agree with the patched trunk:

pr46459.f90:9:11:

   call sub2 (1)         ! { dg-error "Explicit interface required" }
           1
Error: Explicit interface required for 'sub2' at (1): volatile argument
Comment 8 janus 2016-11-09 10:36:12 UTC
As mentioned by Harald, the patch in comment 1 works well and is close to obvious.

Mikael, are you going to commit this, or do you want me to do it?
Comment 9 janus 2016-11-09 10:59:17 UTC
(In reply to janus from comment #8)
> As mentioned by Harald, the patch in comment 1 works well and is close to
> obvious.


I verified that it regtests cleanly. Adapted to current trunk it looks like this:

Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(Revision 241993)
+++ gcc/fortran/interface.c	(Arbeitskopie)
@@ -3190,6 +3190,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gf
 	 shape array, if the dummy argument has the VOLATILE attribute.  */
 
       if (f->sym->attr.volatile_
+	  && a->expr->expr_type == EXPR_VARIABLE
 	  && a->expr->symtree->n.sym->as
 	  && a->expr->symtree->n.sym->as->type == AS_ASSUMED_SHAPE
 	  && !(f->sym->as && f->sym->as->type == AS_ASSUMED_SHAPE))
@@ -3219,6 +3220,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gf
 	 dummy argument has the VOLATILE attribute.  */
 
       if (f->sym->attr.volatile_
+	  && a->expr->expr_type == EXPR_VARIABLE
 	  && a->expr->symtree->n.sym->attr.pointer
 	  && a->expr->symtree->n.sym->as
 	  && !(f->sym->as
Comment 10 Mikael Morin 2016-11-09 19:22:22 UTC
(In reply to janus from comment #8)
> As mentioned by Harald, the patch in comment 1 works well and is close to
> obvious.
> 
> Mikael, are you going to commit this, or do you want me to do it?

Please do, I lack some time for gfortran these days.
Comment 11 janus 2016-11-09 20:33:56 UTC
Author: janus
Date: Wed Nov  9 20:33:24 2016
New Revision: 242020

URL: https://gcc.gnu.org/viewcvs?rev=242020&root=gcc&view=rev
Log:
2016-11-09  Mikael Morin  <mikael@gcc.gnu.org>
	    Janus Weil  <janus@gcc.gnu.org>

	PR fortran/46459
	* interface.c (compare_actual_formal): Add safety checks to avoid ICE.

2016-11-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/46459
	* gfortran.dg/volatile14.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/volatile14.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 janus 2016-11-09 20:37:24 UTC
(In reply to Mikael Morin from comment #10)
> Please do, I lack some time for gfortran these days.

I have committed the fix as r242020. Closing.