Patchwork [Fortran,(RFC)] PR49110/51055 Assignment to alloc. deferred-length character vars

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 11, 2012, 6:37 p.m.
Message ID <20121211183753.GV2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/205289/
State New
Headers show

Comments

Jakub Jelinek - Dec. 11, 2012, 6:37 p.m.
On Tue, Dec 11, 2012 at 02:29:18PM +0100, Janus Weil wrote:
> 2012/12/11 Jakub Jelinek <jakub@redhat.com>:
> > On Tue, Dec 11, 2012 at 12:16:33PM +0100, Janus Weil wrote:
> >> Ok, so here is a new patch, updated according to the suggestions of
> >> David and Jakub. This now only touches the dotted variables, which are
> >> responsible for the AIX trouble. Whether the same prefixing should
> >> also be applied in other cases, we can still decide later.
> >
> > Why are you changing anything in create_function_arglist (PARM_DECLs
> > can't ever be TREE_STATIC, and it is compiler internal (plus debug info)
> > thing how they are named, no need for any kind of mangling) or
> > saved_dovar (again, doesn't seem to be TREE_STATIC)?
> >
> > Even in gfc_create_string_length you don't need to increase the length
> > of the names and obfuscate them if it isn't going to be TREE_STATIC.
> 
> Yes, you're probably right.
> 
> Anyway, I'm out. I don't have the capacities to deal with this right
> now (and, frankly, it's not my duty anyway) ...

So, what about this version instead?

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-12-11  Jakub Jelinek  <jakub@redhat.com>
	    Janus Weil  <janus@gcc.gnu.org>

	PR fortran/55636
	* gfortran.h (GFC_PREFIX): Define.
	* trans-decl.c (gfc_create_string_length): For VAR_DECLs that
	will be TREE_STATIC, use GFC_PREFIX to mangle the names.


	Jakub
David Edelsohn - Dec. 12, 2012, 2:16 a.m.
On Tue, Dec 11, 2012 at 1:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:

> So, what about this version instead?
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2012-12-11  Jakub Jelinek  <jakub@redhat.com>
>             Janus Weil  <janus@gcc.gnu.org>
>
>         PR fortran/55636
>         * gfortran.h (GFC_PREFIX): Define.
>         * trans-decl.c (gfc_create_string_length): For VAR_DECLs that
>         will be TREE_STATIC, use GFC_PREFIX to mangle the names.
>
> --- gcc/fortran/gfortran.h.jj   2012-12-04 14:17:30.574177056 +0100
> +++ gcc/fortran/gfortran.h      2012-12-11 15:48:37.967422227 +0100
> @@ -63,6 +63,15 @@ along with GCC; see the file COPYING3.
>  #define PREFIX(x) "_gfortran_" x
>  #define PREFIX_LEN 10
>
> +/* A prefix for internal variables, which are not user-visible.  */
> +#if !defined (NO_DOT_IN_LABEL)
> +# define GFC_PREFIX(x) "_F." x
> +#elif !defined (NO_DOLLAR_IN_LABEL)
> +# define GFC_PREFIX(x) "_F$" x
> +#else
> +# define GFC_PREFIX(x) "_F_" x
> +#endif
> +
>  #define BLANK_COMMON_NAME "__BLNK__"
>
>  /* Macro to initialize an mstring structure.  */
> --- gcc/fortran/trans-decl.c.jj 2012-12-11 09:25:18.757189184 +0100
> +++ gcc/fortran/trans-decl.c    2012-12-11 15:50:13.487857146 +0100
> @@ -1090,7 +1090,15 @@ gfc_create_string_length (gfc_symbol * s
>        const char *name;
>
>        /* Also prefix the mangled name.  */
> -      if (sym->module)
> +      if (sym->attr.save || sym->ns->proc_name->attr.flavor == FL_MODULE)
> +       {
> +         if (sym->module)
> +           name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
> +                                  sym->name);
> +         else
> +           name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
> +       }
> +      else if (sym->module)
>         name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
>        else
>         name = gfc_get_string (".%s", sym->name);

Why are you only correcting the prefix for attr.save or FL_MODULE?
Why leave the dot name in the other cases?

Thanks, David
Jakub Jelinek - Dec. 18, 2012, 2:17 p.m.
On Tue, Dec 11, 2012 at 09:16:53PM -0500, David Edelsohn wrote:
> > @@ -1090,7 +1090,15 @@ gfc_create_string_length (gfc_symbol * s
> >        const char *name;
> >
> >        /* Also prefix the mangled name.  */
> > -      if (sym->module)
> > +      if (sym->attr.save || sym->ns->proc_name->attr.flavor == FL_MODULE)
> > +       {
> > +         if (sym->module)
> > +           name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
> > +                                  sym->name);
> > +         else
> > +           name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
> > +       }
> > +      else if (sym->module)
> >         name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
> >        else
> >         name = gfc_get_string (".%s", sym->name);
> 
> Why are you only correcting the prefix for attr.save or FL_MODULE?
> Why leave the dot name in the other cases?

Because otherwise it is just an automatic variable, i.e. doesn't make it
into assembly in any way appart from possibly debug info DW_AT_name (where it is
desirable to have shorter names).
It could have similarly just name = NULL for those (just would make dumps
slightly less readable).

	Jakub
Tobias Burnus - Dec. 18, 2012, 3:40 p.m.
Jakub Jelinek wrote:
> So, what about this version instead?
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 2012-12-11  Jakub Jelinek<jakub@redhat.com>
> 	    Janus Weil<janus@gcc.gnu.org>
>
> 	PR fortran/55636
> 	* gfortran.h (GFC_PREFIX): Define.
> 	* trans-decl.c (gfc_create_string_length): For VAR_DECLs that
> 	will be TREE_STATIC, use GFC_PREFIX to mangle the names.>         /* Also prefix the mangled name.  */
> -      if (sym->module)
> +      if (sym->attr.save || sym->ns->proc_name->attr.flavor == FL_MODULE)
> +	{
> +	  if (sym->module)
> +	    name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
> +				   sym->name);
> +	  else
> +	    name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
> +	}
> +      else if (sym->module)
>   	name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
>         else
>   	name = gfc_get_string (".%s", sym->name);

Looks mostly okay, however, I fear that for

subroutine foo()
character(len=:), allocatable :: str
allocate(str, stat=istat)
end subroutine foo

compiled with "-fno-automatic", gfortran will still generate the 
non-GFC_PREFIX-mangled string.

"-fno-automatic" implies SAVE / static memory and is required by some 
old code. Hence, it is unlikely to be used with new code; still, 
gfortran should get this right. (Actually, as PR55733 shows, there are 
issues beyond the mangling with -fno-automatic for deferred-length 
strings/scalar allocatables).

Thus, I wonder whether one should always use GFC_PREFIX. On the other 
hand, for scan-tree-dump, it is nice to have a single mangling instead 
of 3 different ones. (Though, currently, no scan-tree-dump seems to be 
used in this case.)

Hence:

OK with either always using GFC_PREFIX – or with an additional "&& 
gfc_option.flag_max_stack_var_size == 0" check and a comment why the 
mangling is done.

Tobias
Jakub Jelinek - Dec. 18, 2012, 4:28 p.m.
On Tue, Dec 18, 2012 at 04:40:10PM +0100, Tobias Burnus wrote:
> Looks mostly okay, however, I fear that for
> 
> subroutine foo()
> character(len=:), allocatable :: str
> allocate(str, stat=istat)
> end subroutine foo
> 
> compiled with "-fno-automatic", gfortran will still generate the
> non-GFC_PREFIX-mangled string.

That doesn't compile:
Error: Allocate-object at (1) with a deferred type parameter requires either a type-spec or SOURCE tag or a MOLD tag

Where would be TREE_STATIC set on the length variable with -fno-automatic,
and on which testcase?

	Jakub
Jakub Jelinek - Dec. 18, 2012, 4:35 p.m.
On Tue, Dec 18, 2012 at 05:28:09PM +0100, Jakub Jelinek wrote:
> On Tue, Dec 18, 2012 at 04:40:10PM +0100, Tobias Burnus wrote:
> > Looks mostly okay, however, I fear that for
> > 
> > subroutine foo()
> > character(len=:), allocatable :: str
> > allocate(str, stat=istat)
> > end subroutine foo
> > 
> > compiled with "-fno-automatic", gfortran will still generate the
> > non-GFC_PREFIX-mangled string.
> 
> That doesn't compile:
> Error: Allocate-object at (1) with a deferred type parameter requires either a type-spec or SOURCE tag or a MOLD tag
> 
> Where would be TREE_STATIC set on the length variable with -fno-automatic,
> and on which testcase?

subroutine foo(n)
integer :: n
character(len=n + 8), allocatable :: str
allocate(str, stat=istat)
end subroutine foo

compiles with -fno-automatic, but the length var (unlike str var) is clearly
not TREE_STATIC in that case:

        .local  str.1877
        .comm   str.1877,8,8
...
        .uleb128 0x5    # (DIE (0x71) DW_TAG_variable)
        .ascii "str\0"  # DW_AT_name
        .byte   0x1     # DW_AT_decl_file (x.f90)
        .byte   0x3     # DW_AT_decl_line
        .long   0xc2    # DW_AT_type
        .uleb128 0x9    # DW_AT_location
        .byte   0x3     # DW_OP_addr
        .quad   str.1877
        .uleb128 0x6    # (DIE (0x86) DW_TAG_variable)
        .long   .LASF5  # DW_AT_name: ".str"
        .long   0xb6    # DW_AT_type
                        # DW_AT_artificial
        .uleb128 0x2    # DW_AT_location
        .byte   0x91    # DW_OP_fbreg
        .sleb128 -36

(and as can be seen, the dot name makes it through into debug info, but not
assembly outside of DW_AT_name).

	Jakub

Patch

--- gcc/fortran/gfortran.h.jj	2012-12-04 14:17:30.574177056 +0100
+++ gcc/fortran/gfortran.h	2012-12-11 15:48:37.967422227 +0100
@@ -63,6 +63,15 @@  along with GCC; see the file COPYING3.
 #define PREFIX(x) "_gfortran_" x
 #define PREFIX_LEN 10
 
+/* A prefix for internal variables, which are not user-visible.  */
+#if !defined (NO_DOT_IN_LABEL)
+# define GFC_PREFIX(x) "_F." x
+#elif !defined (NO_DOLLAR_IN_LABEL)
+# define GFC_PREFIX(x) "_F$" x
+#else
+# define GFC_PREFIX(x) "_F_" x
+#endif
+
 #define BLANK_COMMON_NAME "__BLNK__"
 
 /* Macro to initialize an mstring structure.  */
--- gcc/fortran/trans-decl.c.jj	2012-12-11 09:25:18.757189184 +0100
+++ gcc/fortran/trans-decl.c	2012-12-11 15:50:13.487857146 +0100
@@ -1090,7 +1090,15 @@  gfc_create_string_length (gfc_symbol * s
       const char *name;
 
       /* Also prefix the mangled name.  */
-      if (sym->module)
+      if (sym->attr.save || sym->ns->proc_name->attr.flavor == FL_MODULE)
+	{
+	  if (sym->module)
+	    name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
+				   sym->name);
+	  else
+	    name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
+	}
+      else if (sym->module)
 	name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
       else
 	name = gfc_get_string (".%s", sym->name);