http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218
--- Comment #2 from janus at gcc dot gnu.org 2013-02-06 10:08:59 UTC ---
Here is a draft patch, which seems to fix the test case:
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c (revision 195644)
+++ gcc/fortran/trans-decl.c (working copy)
@@ -3505,6 +3505,15 @@ init_intent_out_dt (gfc_symbol * proc_sym, gfc_wra
present, tmp,
build_empty_stmt (input_location));
}
+ else if (CLASS_DATA (f->sym)->attr.allocatable)
+ {
+ present = gfc_class_data_get (f->sym->backend_decl);
+ present = fold_build2_loc (input_location, NE_EXPR,
+ boolean_type_node, present,
+ fold_convert (TREE_TYPE (present), null_pointer_node));
+ tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
+ present, tmp, build_empty_stmt (input_location));
+ }
gfc_add_expr_to_block (&init, tmp);
}
I think the same problem exists with TYPE(foo_t) instead of CLASS(foo_t), which
is not yet handled by the patch. However I do not get a valgrind failure for
the TYPE version for some reason.
In fact, I'm not sure if we correctly pass the argument to 'do_stuff' for the
TYPE version:
struct foo_t * f;
[...]
f = 0B;
do_stuff (&f);
If I'm not missing anything, I think we should pass 'f' directly instead of
'&f':
do_stuff (struct foo_t * & restrict f)
{
if (f->a.data != 0B)
{
__builtin_free ((void *) f->a.data);
}
f->a.data = 0B;
}