Hi!

As I said earlier in the PR, I don't like -fbroken-callers option much,
as the option name doesn't hint what it is doing at all.

The following patch renames the option and makes it into a 3 state option,
with the default being a middle-ground, where it avoids the tail calls in
functions that have the hidden character length arguments only if it makes
any implicit interface calls.  The rationale for that is that there were no
previously reported issues with older GCC versions and the change that
affected the broken C/C++ wrappers was just giving prototypes to the
implicit interface procedure calls, so presumably in functions that don't
have any such calls nothing should have changed.

Bootstrapped/regtested on x86_64-linux and i686-linux, additionally tested
on the dtrtri.f testcase and on dtrtri.f testcase patched to include
explicit interfaces for all called procedures (and for those two verified
all the 6 ways of using these options, default, positive/negative option
without = and 0/1/2 values of the = option, checking in which case there is
a tail call), ok for trunk?

2019-05-29  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/90329
        * lang.opt (fbroken-callers): Remove.
        (ftail-call-workaround, ftail-call-workaround=): New options.
        * gfortran.h (struct gfc_namespace): Add implicit_interface_calls.
        * interface.c (gfc_procedure_use): Set implicit_interface_calls
        for calls to implicit interface procedures.
        * trans-decl.c (create_function_arglist): Use flag_tail_call_workaround
        instead of flag_broken_callers.  If it is not 2, also require
        sym->ns->implicit_interface_calls.
        * invoke.texi (fbroken-callers): Remove documentation.
        (ftail-call-workaround, ftail-call-workaround=): Document.

--- gcc/fortran/lang.opt.jj     2019-05-23 12:57:17.759475698 +0200
+++ gcc/fortran/lang.opt        2019-05-28 19:28:39.111359365 +0200
@@ -397,10 +397,6 @@ fblas-matmul-limit=
 Fortran RejectNegative Joined UInteger Var(flag_blas_matmul_limit) Init(30)
 -fblas-matmul-limit=<n>        Size of the smallest matrix for which matmul 
will use BLAS.
 
-fbroken-callers
-Fortran Var(flag_broken_callers) Init(1)
-Disallow tail call optimization when a calling routine may have omitted 
character lenghts.
-
 fcheck-array-temporaries
 Fortran
 Produce a warning at runtime if a array temporary has been created for a 
procedure argument.
@@ -766,6 +762,13 @@ fsign-zero
 Fortran Var(flag_sign_zero) Init(1)
 Apply negative sign to zero values.
 
+ftail-call-workaround
+Frotran Alias(ftail-call-workaround=,1,0)
+
+ftail-call-workaround=
+Fortran RejectNegative Joined UInteger IntegerRange(0, 2) 
Var(flag_tail_call_workaround) Init(1)
+Disallow tail call optimization when a calling routine may have omitted 
character lenghts.
+
 funderscoring
 Fortran Var(flag_underscoring) Init(1)
 Append underscores to externally visible names.
--- gcc/fortran/gfortran.h.jj   2019-05-10 09:31:29.548146009 +0200
+++ gcc/fortran/gfortran.h      2019-05-28 19:18:17.776456590 +0200
@@ -1866,6 +1866,9 @@ typedef struct gfc_namespace
 
   /* Set to 1 for !$ACC ROUTINE namespaces.  */
   unsigned oacc_routine:1;
+
+  /* Set to 1 if there are any calls to procedures with implicit interface.  */
+  unsigned implicit_interface_calls:1;
 }
 gfc_namespace;
 
--- gcc/fortran/interface.c.jj  2019-05-10 23:20:36.072731478 +0200
+++ gcc/fortran/interface.c     2019-05-28 19:23:05.551779996 +0200
@@ -3686,6 +3686,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_
        gfc_warning (OPT_Wimplicit_procedure,
                     "Procedure %qs called at %L is not explicitly declared",
                     sym->name, where);
+      gfc_find_proc_namespace (sym->ns)->implicit_interface_calls = 1;
     }
 
   if (sym->attr.if_source == IFSRC_UNKNOWN)
--- gcc/fortran/trans-decl.c.jj 2019-05-20 11:39:33.392827300 +0200
+++ gcc/fortran/trans-decl.c    2019-05-28 19:33:25.847699650 +0200
@@ -2520,9 +2520,12 @@ create_function_arglist (gfc_symbol * sy
          /* Marking the length DECL_HIDDEN_STRING_LENGTH will lead
             to tail calls being disabled.  Only do that if we
             potentially have broken callers.  */
-         if (flag_broken_callers && f->sym->ts.u.cl
+         if (flag_tail_call_workaround
+             && f->sym->ts.u.cl
              && f->sym->ts.u.cl->length
-             && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
+             && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
+             && (flag_tail_call_workaround == 2
+                 || f->sym->ns->implicit_interface_calls))
            DECL_HIDDEN_STRING_LENGTH (length) = 1;
 
          /* Remember the passed value.  */
--- gcc/fortran/invoke.texi.jj  2019-05-23 12:57:17.761475665 +0200
+++ gcc/fortran/invoke.texi     2019-05-28 19:45:59.752653839 +0200
@@ -181,7 +181,8 @@ and warnings}.
 @item Code Generation Options
 @xref{Code Gen Options,,Options for code generation conventions}.
 @gccoptlist{-faggressive-function-elimination -fblas-matmul-limit=@var{n} @gol
--fbounds-check -fbroken-callers -fcheck-array-temporaries @gol
+-fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol
+-fcheck-array-temporaries @gol
 -fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>} @gol
 -fcoarray=@var{<none|single|lib>} -fexternal-blas -ff2c
 -ffrontend-loop-interchange @gol
@@ -1622,8 +1623,9 @@ warnings for generated array temporaries
 @c Note: This option is also referred in gcc's manpage
 Deprecated alias for @option{-fcheck=bounds}.
 
-@item -fbroken-callers
-@opindex @code{broken-callers}
+@item -ftail-call-workaround
+@itemx -ftail-call-workaround=@var{n}
+@opindex @code{tail-call-workaround}
 Some C interfaces to Fortran codes violate the gfortran ABI by
 omitting the hidden character length arguments as described in
 @xref{Argument passing conventions}.  This can lead to crashes
@@ -1631,7 +1633,11 @@ because pushing arguments for tail calls
 
 To provide a workaround for existing binary packages, this option
 disables tail call optimization for gfortran procedures with character
-arguments.
+arguments.  With @option{-ftail-call-workaround=2} tail call optimization
+is disabled in all gfortran procedures with character arguments,
+with @option{-ftail-call-workaround=1} or equivalent
+@option{-ftail-call-workaround} only in gfortran procedures with character
+arguments that call implicitly prototyped procedures.
 
 Using this option can lead to problems including crashes due to
 insufficient stack space.
@@ -1644,10 +1650,10 @@ source code.
 Support for this option will likely be withdrawn in a future release
 of gfortran.
 
-The negative form, @option{-fno-broken-callers}, can be used to
-disable this option.
+The negative form, @option{-fno-tail-call-workaround} or equivalent
+@option{-ftail-call-workaround=0}, can be used to disable this option.
 
-Default is currently @option{-fbroken-callers}, this will change
+Default is currently @option{-ftail-call-workaround}, this will change
 in future releases.
 
 @item -fcheck-array-temporaries

        Jakub

Reply via email to