Bug 40089 - Public type with public component which has a private type
Summary: Public type with public component which has a private type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-10 09:37 UTC by janus
Modified: 2009-05-11 14:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-05-11 09:55:35


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2009-05-10 09:37:08 UTC
Please consider the following code:


module m

  implicit none
  private

  public :: public_t
  public :: public_sub
  !public :: private_t	(*)

  type :: private_t
    integer :: i
  end type

  type :: public_t
     type(private_t), pointer :: public_comp_with_private_type	!(#1)
     procedure(ifc) , nopass, pointer :: ppc
  end type

  abstract interface
     integer function ifc ()
     end function
  end interface

  type(private_t), save, public :: public_var_with_private_type	!(#2)

contains

  subroutine public_sub(arg)	!(#3)
    type(private_t) :: arg
  end subroutine

end module m

program test
use m
implicit none
type(public_t) :: x
integer :: j
print *,public_var_with_private_type%i
j = x%ppc()  ! Error: Can't convert UNKNOWN to INTEGER(4)
end


With current trunk versions of gfortran, this produces the error indicated in the last line of the program. Of course this error is bogus, since ppc has an explicit interface (with an integer return type).

However, I believe this program is invalid for the following reason: The type 'public_t' is public in the module m, and it has a public component, indicated by (#1), whose type is private in the module. So this component is accessible outside of the module, but its type is not.

Up to now I was not able to find a rule in the F03 Standard, which explicitly forbids this. But my common sense tells me that it should be invalid (hoping my common sense works alright).

Following the same reasoning, the cases (#2) and (#3) should be invalid, too, but none of them is detected by gfortran. Unfortunately, I could not find any other compiler which rejects the program (ifort and g95 accept it). Still I think it is invalid.

If the line indicated by (*) is uncommented, the error message goes away. With this modification the program should be valid, and all is fine.

Thanks to Juergen Reuter for reporting this.
Comment 1 Tobias Burnus 2009-05-11 08:07:58 UTC
Without heavily thinking about it:

> print *,public_var_with_private_type%i

Seems to be valid in Fortran 2003 (but not in 2003). The components are not PRIVATE and thus accessibly, even if the TYPE declaration is not accessible. (I think one only needs the TYPE to declare new variables of this type not to access components of existing entities of that type.)

> j = x%ppc()

Seems to be valid: The PPC has an explicit interface and thus there is no need for implicit typing.

Thus I would reason that g95, ifort and NAG (assuming Juergen Reuter is using it) are correct in accepting it. -- I can try to find it in the standard, but it is not a simple constraint which one can find but it is rather written between the lines.
Comment 2 janus 2009-05-11 08:23:08 UTC
> Thus I would reason that g95, ifort and NAG (assuming Juergen Reuter is using
> it) are correct in accepting it.

NAG indeed accepts it with -f2003. With -f95 it reports

Extension: c0.f90, line 32: Dummy ARG of PUBLIC_SUB exposes PRIVATE type PRIVATE_T detected at M@<end-of-statement>
Extension: c0.f90, line 32: Variable PUBLIC_VAR_WITH_PRIVATE_TYPE exposes PRIVATE type PRIVATE_T detected at M@<end-of-statement>
Extension: c0.f90, line 32: Component PUBLIC_COMP_WITH_PRIVATE_TYPE of type PUBLIC_T exposes PRIVATE type PRIVATE_T detected at M@<end-of-statement>

Probably it is really valid in F2003, and my common sense just failed. I will try to fix gfortran's bogus error.
Comment 3 janus 2009-05-11 09:55:34 UTC
Actually gfortran even has the same check as NAG that rejects a private type as component of a public type with -std=f95. And it happens that the bug which leads to the bogus error message lies just in this check. Thus the fix is easy:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 147349)
+++ gcc/fortran/resolve.c	(working copy)
@@ -9088,11 +9088,11 @@ resolve_fl_derived (gfc_symbol *sym)
 	  && !gfc_check_access (c->ts.derived->attr.access,
 				c->ts.derived->ns->default_access))
 	{
-	  gfc_notify_std (GFC_STD_F2003, "Fortran 2003: the component '%s' "
+	  if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: the component '%s' "
 			  "is a PRIVATE type and cannot be a component of "
 			  "'%s', which is PUBLIC at %L", c->name,
-			  sym->name, &sym->declared_at);
-	  return FAILURE;
+			  sym->name, &sym->declared_at) == FAILURE)
+	    return FAILURE;
 	}
 
       if (sym->attr.sequence)
Comment 4 Tobias Burnus 2009-05-11 10:20:47 UTC
>           && !gfc_check_access (c->ts.derived->attr.access,
>                                 c->ts.derived->ns->default_access))
>         {
> -         gfc_notify_std (GFC_STD_F2003, "Fortran 2003: the component '%s' "
> +         if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: the component '%s'
> "

Or shorter:

 if (....
     && !gfc_check_access
     && gfc_notify_std (...) == FAILURE)
   return FAILURE;

saves a { } pair and some indentation
Comment 5 janus 2009-05-11 14:14:54 UTC
Subject: Bug 40089

Author: janus
Date: Mon May 11 14:14:38 2009
New Revision: 147379

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147379
Log:
2009-05-11  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40089
	* resolve.c (resolve_fl_derived): Only return FAILURE if
	gfc_notify_std fails.


2009-05-11  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40089
	* gfortran.dg/proc_ptr_comp_7.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_comp_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog

Comment 6 janus 2009-05-11 14:19:02 UTC
Fixed with r147379. Closing.