Patchwork [Fortran] PR53175 - Fix another fallout of the TREE_PUBLIC=0 module variable patch

login
register
mail settings
Submitter Tobias Burnus
Date May 3, 2012, 6:41 p.m.
Message ID <4FA2D152.8010807@net-b.de>
Download mbox | patch
Permalink /patch/156761/
State New
Headers show

Comments

Tobias Burnus - May 3, 2012, 6:41 p.m.
A PRIVATE module variable, which is used in the specification expression 
of a function result variable cannot be TREE_PUBLIC()=0, unless the 
function itself is PRIVATE and also not accessible via type-bound 
procedures or a generic name. (The issue is gfortran specific as most 
compilers do not seem to save the specification expression in the .mod 
file.)

Build and regtested on x86-64-linux.
OK for the trunk?

Tobias
Paul Richard Thomas - May 4, 2012, 12:27 p.m.
Dear Tobias,

This is OK for trunk.

Thanks for the patch.

Paul

On 3 May 2012 20:41, Tobias Burnus <burnus@net-b.de> wrote:
> A PRIVATE module variable, which is used in the specification expression of
> a function result variable cannot be TREE_PUBLIC()=0, unless the function
> itself is PRIVATE and also not accessible via type-bound procedures or a
> generic name. (The issue is gfortran specific as most compilers do not seem
> to save the specification expression in the .mod file.)
>
> Build and regtested on x86-64-linux.
> OK for the trunk?
>
> Tobias
>

Patch

2012-05-03  Tobias Burnus  <burnus@net-b.de>

	PR fortran/53175
	* resolve.c (resolve_variable): Set public_used
	if a private module variable is used in a (public)
	specification expression.
	* trans-decl.c (gfc_finish_var_decl): Mark those
	TREE_PUBLIC.

2012-05-03  Tobias Burnus  <burnus@net-b.de>

	PR fortran/53175
	gfortran.dg/public_private_module_5.f90: New.

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 57da577..e15d6e1 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5124,6 +5124,19 @@  resolve_variable (gfc_expr *e)
   if (check_assumed_size_reference (sym, e))
     return FAILURE;
 
+  /* If a PRIVATE variable is used in the specification expression of the
+     result variable, it might be accessed from outside the module and can
+     thus not be TREE_PUBLIC() = 0.
+     TODO: sym->attr.public_used only has to be set for the result variable's
+     type-parameter expression and not for dummies or automatic variables.
+     Additionally, it only has to be set if the function is either PUBLIC or
+     used in a generic interface or TBP; unfortunately,
+     proc_name->attr.public_used can get set at a later stage.  */
+  if (specification_expr && sym->attr.access == ACCESS_PRIVATE
+      && !sym->attr.function && !sym->attr.use_assoc
+      && gfc_current_ns->proc_name && gfc_current_ns->proc_name->attr.function)
+    sym->attr.public_used = 1;
+
   /* Deal with forward references to entries during resolve_code, to
      satisfy, at least partially, 12.5.2.5.  */
   if (gfc_current_ns->entries
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index d6c090e..9196f0a 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -565,7 +565,7 @@  gfc_finish_var_decl (tree decl, gfc_symbol * sym)
       /* TODO: Don't set sym->module for result or dummy variables.  */
       gcc_assert (current_function_decl == NULL_TREE || sym->result == sym);
       /* This is the declaration of a module variable.  */
-      if (sym->attr.access != ACCESS_PRIVATE)
+      if (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used)
 	TREE_PUBLIC (decl) = 1;
       TREE_STATIC (decl) = 1;
     }
--- /dev/null	2012-04-23 08:17:57.683771451 +0200
+++ gcc/gcc/testsuite/gfortran.dg/public_private_module_5.f90	2012-05-03 15:11:54.000000000 +0200
@@ -0,0 +1,40 @@ 
+! { dg-do compile }
+! { dg-options "-O3" }
+!
+! PR fortran/53175
+!
+
+MODULE ENERGY_FUNCTION
+   IMPLICIT NONE
+
+   TYPE PARAM
+      PRIVATE
+         INTEGER :: WHICH_VECTOR
+   END TYPE PARAM
+
+   INTEGER, PRIVATE :: DIM2
+   INTEGER, PRIVATE :: DIM5
+
+   private :: specific
+   interface gen
+     module procedure  specific
+   end interface gen
+
+   CONTAINS
+
+      FUNCTION ENERGY_FUNCTION_CURRENT_ARGS()
+         INTEGER, DIMENSION(DIM2) :: ENERGY_FUNCTION_CURRENT_ARGS
+      END FUNCTION ENERGY_FUNCTION_CURRENT_ARGS
+
+      FUNCTION ENERGY_FUNCTION_GET_PARAMS()
+         TYPE(PARAM), DIMENSION(DIM2) :: ENERGY_FUNCTION_GET_PARAMS
+      END FUNCTION ENERGY_FUNCTION_GET_PARAMS   
+
+      function specific()
+        character(len=dim5) :: specific
+      end function specific
+END MODULE ENERGY_FUNCTION
+
+! { dg-final { scan-assembler "__energy_function_MOD_dim2" } }
+! { dg-final { scan-assembler "__energy_function_MOD_dim5" } }
+