https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78618

--- Comment #16 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Sun, Dec 04, 2016 at 10:07:16AM +0000, janus at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78618
> 
> --- Comment #15 from janus at gcc dot gnu.org ---
> (In reply to Steve Kargl from comment #10)
> > This looks like a used-after-freed bug.
> 
> Yes, it does.
> 
> My first suspicion was that the problematic freeing happens at the end of
> variable_decl (decl.c:2450):
> 
>   gfc_free_expr (initializer);
> 
> It seems the initializer here has the same ts.u.cl (not a copy) as the symbol
> 'c'. However, gfc_free_expr (surprisingly) does not free anything in the
> typespec.
> 
> Instead it seems the charlen is freed via gfc_free_charlen in
> 'reject_statement'. Not sure what to do about it ...
> 

Looks like you have done a nice bit of debugging.  I went in a different
direction.  In intrinsic.c (gfc_convert_chartype), I tried to allocate a
gfc_charlen and then copy ts.u.cl from the char(255,4) in the ts.u.cl for
'c'.  This occurs before 'reject_statement', so of course it failed.

I've a possible kludge under testing.  In resolve.c (resolve_fl_procedure),
the offending chunk of code is (line 12013 or so)

    if (cl && cl->length && gfc_is_constant_expr (cl->length)
             && !resolve_charlen (cl))
        return false;

where cl->length is invalid but not NULL.

I simply forced a 'return false' in gdb to see what would
happen, and char_constant.f90 compiled without the ICE error.
Thus, I've came up with

Index: resolve.c
===================================================================
--- resolve.c   (revision 243227)
+++ resolve.c   (working copy)
@@ -12010,6 +12010,9 @@ resolve_fl_procedure (gfc_symbol *sym, i
     {
       gfc_charlen *cl = sym->ts.u.cl;

+      if (strcmp (sym->name, "__convert_s4_s1") == 0)
+       return false;
+
       if (cl && cl->length && gfc_is_constant_expr (cl->length)
             && !resolve_charlen (cl))
        return false;

It's not pretty, but seems to work. :(

Reply via email to