summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/class.c3
-rw-r--r--gcc/fortran/trans-decl.c12
-rw-r--r--gcc/fortran/trans.h1
4 files changed, 27 insertions, 3 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index cd452ab557f..83974b51ca0 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,17 @@
+2011-11-19 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/51207
+ * class.c (gfc_find_derived_vtab): Mark __def_init as PARAMETER
+ and hence as TREE_READONLY; add subroutine attribute to
+ __copy_ procedure.
+
+ PR fortran/50640
+ * trans.h (GFC_DECL_PUSH_TOPLEVEL): New DECL_LANG_FLAG_7.
+ * trans-decl.c (gfc_get_symbol_decl): Mark __def_init and vtab as
+ GFC_DECL_PUSH_TOPLEVEL.
+ (gfc_generate_function_code): If GFC_DECL_PUSH_TOPLEVEL, push it there.
+ (build_function_decl): Push __copy_ procedure to the toplevel.
+
2011-11-16 Tobias Burnus <burnus@net-b.de>
PR fortran/39427
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index dc76ad158bb..bcb2d0b76bc 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -522,7 +522,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
def_init->attr.target = 1;
def_init->attr.save = SAVE_IMPLICIT;
def_init->attr.access = ACCESS_PUBLIC;
- def_init->attr.flavor = FL_VARIABLE;
+ def_init->attr.flavor = FL_PARAMETER;
gfc_set_sym_referenced (def_init);
def_init->ts.type = BT_DERIVED;
def_init->ts.u.derived = derived;
@@ -552,6 +552,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
gfc_get_symbol (name, sub_ns, &copy);
sub_ns->proc_name = copy;
copy->attr.flavor = FL_PROCEDURE;
+ copy->attr.subroutine = 1;
copy->attr.if_source = IFSRC_DECL;
if (ns->proc_name->attr.flavor == FL_MODULE)
copy->module = ns->proc_name->name;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 02c0ed71802..fc8a9ed4e4b 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1471,6 +1471,10 @@ gfc_get_symbol_decl (gfc_symbol * sym)
&& !sym->attr.proc_pointer)
DECL_BY_REFERENCE (decl) = 1;
+ if (sym->attr.vtab
+ || (sym->name[0] == '_' && strncmp ("__def_init", sym->name, 10) == 0))
+ GFC_DECL_PUSH_TOPLEVEL (decl) = 1;
+
return decl;
}
@@ -1891,7 +1895,8 @@ build_function_decl (gfc_symbol * sym, bool global)
/* Layout the function declaration and put it in the binding level
of the current function. */
- if (global)
+ if (global
+ || (sym->name[0] == '_' && strncmp ("__copy", sym->name, 6) == 0))
pushdecl_top_level (fndecl);
else
pushdecl (fndecl);
@@ -5316,7 +5321,10 @@ gfc_generate_function_code (gfc_namespace * ns)
next = DECL_CHAIN (decl);
DECL_CHAIN (decl) = NULL_TREE;
- pushdecl (decl);
+ if (GFC_DECL_PUSH_TOPLEVEL (decl))
+ pushdecl_top_level (decl);
+ else
+ pushdecl (decl);
decl = next;
}
saved_function_decls = NULL_TREE;
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 22033d38d15..8fc7599473d 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -802,6 +802,7 @@ struct GTY((variable_size)) lang_decl {
#define GFC_DECL_CRAY_POINTEE(node) DECL_LANG_FLAG_4(node)
#define GFC_DECL_RESULT(node) DECL_LANG_FLAG_5(node)
#define GFC_DECL_SUBREF_ARRAY_P(node) DECL_LANG_FLAG_6(node)
+#define GFC_DECL_PUSH_TOPLEVEL(node) DECL_LANG_FLAG_7(node)
/* An array descriptor. */
#define GFC_DESCRIPTOR_TYPE_P(node) TYPE_LANG_FLAG_1(node)