+2010-07-29 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/42051
+ PR fortran/44064
+ * class.c (gfc_find_derived_vtab): Accept or discard newly created
+ symbols before returning.
+
2010-07-29 Joseph Myers <joseph@codesourcery.com>
* lang.opt (cpp): Remove Joined and Separate markers.
gfc_find_derived_vtab (gfc_symbol *derived)
{
gfc_namespace *ns;
- gfc_symbol *vtab = NULL, *vtype = NULL;
+ gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
char name[2 * GFC_MAX_SYMBOL_LEN + 8];
ns = gfc_current_ns;
gfc_get_symbol (name, ns, &vtype);
if (gfc_add_flavor (&vtype->attr, FL_DERIVED,
NULL, &gfc_current_locus) == FAILURE)
- return NULL;
+ goto cleanup;
vtype->refs++;
gfc_set_sym_referenced (vtype);
/* Add component '$hash'. */
if (gfc_add_component (vtype, "$hash", &c) == FAILURE)
- return NULL;
+ goto cleanup;
c->ts.type = BT_INTEGER;
c->ts.kind = 4;
c->attr.access = ACCESS_PRIVATE;
/* Add component '$size'. */
if (gfc_add_component (vtype, "$size", &c) == FAILURE)
- return NULL;
+ goto cleanup;
c->ts.type = BT_INTEGER;
c->ts.kind = 4;
c->attr.access = ACCESS_PRIVATE;
/* Add component $extends. */
if (gfc_add_component (vtype, "$extends", &c) == FAILURE)
- return NULL;
+ goto cleanup;
c->attr.pointer = 1;
c->attr.access = ACCESS_PRIVATE;
parent = gfc_get_derived_super_type (derived);
}
}
- return vtab;
+ found_sym = vtab;
+
+cleanup:
+ /* It is unexpected to have some symbols added at resolution or code
+ generation time. We commit the changes in order to keep a clean state. */
+ if (found_sym)
+ gfc_commit_symbols ();
+ else
+ gfc_undo_symbols ();
+
+ return found_sym;
}
--- /dev/null
+! { dg-do compile }
+! { dg-options "-fno-whole-file" }
+!
+! PR fortran/42051
+! PR fortran/44064
+! Access to freed symbols
+!
+! Testcase provided by Damian Rouson <damian@rouson.net>,
+! reduced by Janus Weil <janus@gcc.gnu.org>.
+
+module grid_module
+ implicit none
+ type grid
+ end type
+ type field
+ type(grid) :: mesh
+ end type
+contains
+ real function return_x(this)
+ class(grid) :: this
+ end function
+end module
+
+module field_module
+ use grid_module, only: field,return_x
+ implicit none
+contains
+ subroutine output(this)
+ class(field) :: this
+ print *,return_x(this%mesh)
+ end subroutine
+end module
+
+end
+
+! { dg-final { cleanup-modules "grid_module field_module" } }