[Patch, Fortran, PR58586, v3] ICE with derived type with allocatable component passed by value
Andre Vehreschild
vehre@gmx.de
Fri May 8 10:54:00 GMT 2015
Hi Mikael,
thanks for the review. I still have some questions/remarks before commiting:
On Thu, 07 May 2015 12:14:59 +0200
Mikael Morin <mikael.morin@sfr.fr> wrote:
<snip>
> > @@ -2158,6 +2158,8 @@ build_function_decl (gfc_symbol * sym, bool global)
> > gfc_set_decl_assembler_name (fndecl, gfc_sym_mangled_function_id
> > (sym));
> > sym->backend_decl = fndecl;
> > + if (sym == sym->result && !sym->result->backend_decl)
> > + sym->result->backend_decl = result_decl;
>
> Something is seriously misbehaving if the condition is true, and setting
> sym->backend_decl to result_decl doesn't seem any better than keeping it
> NULL.
> So, please remove this change
Did that. I think this was a relic from the start of me trying to understand
what was the issue and how to fix it. Later I didn't check, if it was still
necessary. Sorry for that.
> > @@ -5898,8 +5900,21 @@ gfc_generate_function_code (gfc_namespace * ns)
> >
> > if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node)
> > {
> > + bool artificial_result_decl = false;
> > tree result = get_proc_result (sym);
> >
> > + /* Make sure that a function returning an object with
> > + alloc/pointer_components always has a result, where at least
> > + the allocatable/pointer components are set to zero. */
> > + if (result == NULL_TREE && sym->attr.function
> > + && sym->ts.type == BT_DERIVED
> > + && (sym->ts.u.derived->attr.alloc_comp
> > + || sym->ts.u.derived->attr.pointer_comp))
> > + {
> > + artificial_result_decl = true;
> > + result = gfc_get_fake_result_decl (sym, 0);
> > + }
>
> I expect the "fake" result decl to be needed in more cases.
> For example, if type is BT_CLASS.
> Here is a variant of alloc_comp_class_4.f03:c_init for such a case.
>
> class(c) function c_init2()
> allocatable :: c_init2
> end function
>
> or even without class:
>
> type(t) function t_init()
> allocatable :: t_init
> end function
>
> for some any type t.
>
> So, remove the check for alloc_comp/pointer_comp and permit BT_CLASS.
> One minor thing, check sym->result's type and attribute instead of sym's
> here. It should not make a difference, but I think it's more correct.
I am d'accord with checking sym->result, but I am not happy with removing the
checks for alloc_comp|pointer_comp. When I got you right there, you propose the
if to be like this:
if (result == NULL_TREE && sym->attr.function
&& (sym->result->ts.type == BT_DERIVED
|| sym->result->ts.type == BT_CLASS))
Removing the attribute checks means to initialize every derived/class type
result, which may change the semantics of the code more than intented. Look for
example at this code
type t
integer :: i = 5
end type
type(t) function static_t_init()
end function
When one compiles this code with -Wreturn-type, then the warning of an
uninitialized return value is issued at the function declaration. Nevertheless
the result of static_t_init is validly initialized and i is 5. This may
confuse users.
I therefore came to the very ugly solution to make this:
if (result == NULL_TREE && sym->attr.function
&& ((sym->result->ts.type == BT_DERIVED
&& (sym->results->attr.allocatable
|| sym->result->ts.u.derived->attr.alloc_comp
|| sym->result->ts.u.derived->attr.pointer_comp))
|| (sym->result->ts.type == BT_CLASS
&& (CLASS_DATA (sym->result)->attr.allocatable
|| CLASS_DATA (sym->result)->attr.alloc_comp
|| CLASS_DATA (sym->result)->attr.pointer_comp))))
(I am not yet sure, whether the pointer attribute needs to be added to.) With
the code above the result of static_t_init is not initialized with all the
consequences.
So what do you propose to do here?
Btw, I think I found an additional bug during testing:
type(t) function t_init()
allocatable :: t_init
end function
when called by:
type(t), allocatable :: temp
temp = t_init()
a segfault occurs, because the result of t_init() is NULL, which is
dereferenced by the caller in this pseudo-code:
if (temp != 0B) goto L.12;
temp = (struct t *) __builtin_malloc (4);
L.12:;
*temp = *t_init (); <-- This obviously is problematic.
> The rest looks good.
> The patch is OK with the suggested changes above. Thanks.
> I don't think the test functions above work well enough to be
> incorporated in a testcase for now.
?? I don't get you there? What do you mean? Do you think the
alloc_comp_class_3/4.* are not correctly testing the issue? Any idea of how to
test this better? I mean the pr is about this artificial constructs. I merely
struck it in search of a pr about allocatable components.
Attached is a version of the patch that I currently use. Note the testcase
alloc_comp_class_4.f03 fails currently, because of the error noted above in
line 94.
Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr58586_4.patch
Type: text/x-patch
Size: 9368 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150508/52ea6b6a/attachment.bin>
More information about the Gcc-patches
mailing list