Bug 49397 - [4.7/4.8/4.9 Regression] [F03] ICE with proc pointer assignment
Summary: [4.7/4.8/4.9 Regression] [F03] ICE with proc pointer assignment
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.8.3
Assignee: Tobias Burnus
URL:
Keywords: diagnostic, ice-on-invalid-code, ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2011-06-13 21:46 UTC by Tobias Burnus
Modified: 2014-02-19 23:53 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-06-13 21:46:08 UTC
Let's claim the following code is valid.

Cf. Intepretation Request J3/11-198 at http://j3-fortran.org/doc/meeting/195/11-198.txt

Without the "print *, f()" line, it is rejected with:
      p => f                           ! (1)
           1
Error: Invalid procedure pointer assignment at (1)

But with the line, one gets:
test.f90: In function 's':
test.f90:2:0: internal compiler error: in build_function_decl, at fortran/trans-decl.c:1778


  Program m5
    Print *,f()
!    Call s
  Contains
    Subroutine s
      Procedure(Real),Pointer :: p
!      Print *,g()
      p => f                           ! (1)
!      Print *,p()
!     p => g                           ! (2)
!     Print *,p()
    End Subroutine
  End Program
  Function f()
    f = 1
  End Function
  Function g()
    g = 2
  End Function
Comment 1 Tobias Burnus 2011-06-14 08:27:44 UTC
More information:

* (2): Case "g" works: If the "print *, g()" as the "p => g" is in the same
  scoping unit, there is no error or ICE.
* (1) If the "print *, f" is in the host of "p => f", there is an ICE.
* (example (3) works - thus not shown, cf. IR 11-198).

My impression is that the error message is OK, but that the assert is wrong. If you change the assert, please make sure it works also with additional nesting due to BLOCK (cf. PR 49400).

The failing assert is:

1774   /* Allow only one nesting level.  Allow public declarations.  */
1775   gcc_assert (current_function_decl == NULL_TREE
1776               || DECL_FILE_SCOPE_P (current_function_decl)
1777               || (TREE_CODE (DECL_CONTEXT (current_function_decl))
1778                   == NAMESPACE_DECL));


The check leading to the error message is generated in gfc_check_pointer_assign:

3349       attr = gfc_expr_attr (rvalue);
3350       if (!((rvalue->expr_type == EXPR_NULL)
3351             || (rvalue->expr_type == EXPR_FUNCTION && attr.proc_pointer)
3352             || (rvalue->expr_type == EXPR_VARIABLE && attr.proc_pointer)
3353             || (rvalue->expr_type == EXPR_VARIABLE
3354                 && attr.flavor == FL_PROCEDURE)))
3355         {
3356           gfc_error ("Invalid procedure pointer assignment at %L",
3357                      &rvalue->where);
3358           return FAILURE;
3359         }
Comment 2 Dominique d'Humieres 2013-06-10 16:39:27 UTC
Still present at revision 199873.
Comment 3 janus 2013-12-11 12:06:15 UTC
(In reply to Tobias Burnus from comment #0)
> Let's claim the following code is valid.
> 
> Cf. Intepretation Request J3/11-198 at
> http://j3-fortran.org/doc/meeting/195/11-198.txt

Btw, the IR confirmed that the code is valid.

The relevant standard quote is F08:C729, which was:

"A procedure-name shall be the name of an internal, module, or dummy procedure, a procedure pointer, an external procedure that is accessed by use or host association and is referenced in the scoping unit as a procedure or that has the EXTERNAL attribute, or a specific intrinsic function listed in 13.6 and not marked with a bullet."

But, according to the IR should be changed to:

"A procedure-name shall be the name of an internal, module, or dummy procedure, a procedure pointer, a specific intrinsic function listed in 13.6 and not marked with a bullet, or an external procedure that is accessed by use or host association, referenced in the scoping unit as a procedure, or that has the EXTERNAL attribute".
Comment 4 janus 2013-12-11 13:12:52 UTC
(In reply to Tobias Burnus from comment #0)
> Without the "print *, f()" line, it is rejected with:
>       p => f                           ! (1)
>            1
> Error: Invalid procedure pointer assignment at (1)

This error message is gone since 4.8 (which is good, since the code is supposed to be valid.

With 4.8 and trunk, unfortunately, both variants give the same ICE.


> But with the line, one gets:
> test.f90: In function 's':
> test.f90:2:0: internal compiler error: in build_function_decl, at
> fortran/trans-decl.c:1778

Note that the ICE does not occur with 4.4.7, but it does at least with 4.6 on upwards (regression!). Have not checked 4.5.
Comment 5 janus 2013-12-11 14:14:48 UTC
Here is a reduced test case for the ICE:


  Print *,f()
Contains
  Subroutine s
    Procedure(Real),Pointer :: p
    p => f 
  End Subroutine
End


No ICE with 4.4 and 4.5, but only with 4.6 and higher. Marking as regression.
Comment 6 janus 2013-12-11 14:34:02 UTC
The ICE is probably due to this commit:

http://gcc.gnu.org/viewcvs/gcc?view=revision&revision=164928
Comment 7 Richard Biener 2013-12-11 14:42:23 UTC
1776               || DECL_FILE_SCOPE_P (current_function_decl)

also matches TRANSLATION_UNIT_DECL.
Comment 8 Tobias Burnus 2014-01-30 23:48:54 UTC
 (In reply to Tobias Burnus from comment #0)
> Cf. Intepretation Request J3/11-198 at
> http://j3-fortran.org/doc/meeting/195/11-198.txt

That became Interpretation Request F08/0060 - see http://j3-fortran.org/doc/year/13/13-006A.txt; passed all ballots and is part of Fortran 2008 Corr. 2.


(In reply to janus from comment #5)
> Here is a reduced test case for the ICE:
>   Print *,f()
> Contains
>   Subroutine s
>     Procedure(Real),Pointer :: p
>     p => f 
>   End Subroutine
> End

The problem seems to be that "f" is not marked as external. That's fixed by the patch below. [ICE on VALID CODE]


However, the following code still ICEs:

Contains
  Subroutine s
    Procedure(Real),Pointer :: p
    p => g
  End Subroutine
End

That's invalid (C729: "... or an external procedure that is accessed by use or host association, referenced in the scoping unit as a procedure, or that has the EXTERNAL attribute".)

Thus, we need to issue an error in this case. (ICE on INVALID) - it currently ICEs even with the patch below.


--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -2872,4 +2872,8 @@ resolve_function (gfc_expr *expr)
   if (sym && is_external_proc (sym))
-    resolve_global_procedure (sym, &expr->where,
-			      &expr->value.function.actual, 0);
+    {
+      resolve_global_procedure (sym, &expr->where,
+				&expr->value.function.actual, 0);
+      if (sym->attr.if_source == IFSRC_UNKNOWN)
+	sym->attr.external = 1;
+    }
Comment 9 Tobias Burnus 2014-01-31 00:10:44 UTC
(In reply to Tobias Burnus from comment #8)
> However, the following code still ICEs:

That's fixed by the following patch.

--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3583,2 +3583,12 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr
 
+      /* Check F2008Cor2, C729.  */
+      if (!s2->attr.intrinsic && s2->attr.if_source == IFSRC_UNKNOWN
+	  && !s2->attr.external && !s2->attr.subroutine && !s2->attr.function)
+	{
+	  gfc_error ("Procedure pointer target '%s' at %L must be either an "
+		     "intrinsic, host or use associated, referenced or have "
+		     "the EXTERNAL attribute", s2->name, &rvalue->where);
+	  return false;
+	}
+
       return true;
Comment 10 Tobias Burnus 2014-02-18 20:44:20 UTC
Patch http://gcc.gnu.org/ml/gcc-patches/2014-02/msg01065.html
Comment 11 Tobias Burnus 2014-02-18 22:10:12 UTC
Author: burnus
Date: Tue Feb 18 22:09:39 2014
New Revision: 207854

URL: http://gcc.gnu.org/viewcvs?rev=207854&root=gcc&view=rev
Log:
2014-02-18  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49397
        * expr.c (gfc_check_pointer_assign): Add check for
        F2008Cor2, C729.
        * trans-decl.c (gfc_get_symbol_decl): Correctly generate
        * external
        decl in a corner case.

2014-02-18  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49397
        * gfortran.dg/proc_ptr_45.f90: New.
        * gfortran.dg/proc_ptr_46.f90: New.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 janus 2014-02-18 22:16:57 UTC
(In reply to Tobias Burnus from comment #11)
> Modified:
>     trunk/gcc/fortran/ChangeLog
>     trunk/gcc/fortran/expr.c
>     trunk/gcc/fortran/trans-decl.c
>     trunk/gcc/testsuite/ChangeLog

Seems like you forgot to "svn add" the test cases?
Comment 13 Tobias Burnus 2014-02-18 22:29:32 UTC
Author: burnus
Date: Tue Feb 18 22:29:00 2014
New Revision: 207855

URL: http://gcc.gnu.org/viewcvs?rev=207855&root=gcc&view=rev
Log:
Really add the new testsuite files missing from commit r207854

2014-02-18  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49397
        * gfortran.dg/proc_ptr_45.f90: New.
        * gfortran.dg/proc_ptr_46.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_45.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_46.f90
Comment 14 Tobias Burnus 2014-02-19 23:33:18 UTC
Author: burnus
Date: Wed Feb 19 23:32:46 2014
New Revision: 207927

URL: http://gcc.gnu.org/viewcvs?rev=207927&root=gcc&view=rev
Log:
2014-02-19  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49397
        * expr.c (gfc_check_pointer_assign): Add check for
        F2008Cor2, C729.
        * trans-decl.c (gfc_get_symbol_decl): Correctly generate
        external decl in a corner case.

2014-02-19  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49397
        * gfortran.dg/proc_ptr_45.f90: New.
        * gfortran.dg/proc_ptr_46.f90: New.


Added:
    branches/gcc-4_8-branch/gcc/testsuite/gfortran.dg/proc_ptr_45.f90
    branches/gcc-4_8-branch/gcc/testsuite/gfortran.dg/proc_ptr_46.f90
Modified:
    branches/gcc-4_8-branch/gcc/fortran/ChangeLog
    branches/gcc-4_8-branch/gcc/fortran/expr.c
    branches/gcc-4_8-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Comment 15 Tobias Burnus 2014-02-19 23:53:21 UTC
Fixed on the trunk (4.9) and on the 4.8 branch.

For 4.7, the valid test case fails due to other bugs. Thus, I decided it is not worthwhile to adapt the patch for 4.7.

Hence, I close this bug as FIXED.