From 5ce039dfe917d694bef1ecb16844f3b1bcb7ed09 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 12 May 2015 00:24:33 +0200 Subject: [PATCH] class.c (fixup_type_variants): Do not copy TYPE_METHODS * class.c (fixup_type_variants): Do not copy TYPE_METHODS (one_inheriting_sig): Assert tat we always set TYPE_METHODS of main variant. * semantics.c (finish_member_declaration): Likewise. * method.c (lazily_declare_fn): Allways add method to main variant list. * dwarf2out.c (gen_member_die): Sanity check that we access TYPE_MAIN_VARIANT for TYPE_METHODS. * function.c (use_register_for_decl): Look for TYPE_MAIN_VARIANT when checking TYPE_METHODS. * tree.c (free_lang_data_in_type): See TYPE_METHODS to error_mark_node if non-null. (build_distinct_type_copy): Clear TYPE_METHODS. (verify_type_variant): Verify that TYPE_METHODS is NULL for variants. (verify_type): Allow TYPE_METHODS to be error_mark_node. * tree.def: Update docs of YTPE_STUB_DECL and TYPE_METHODS. From-SVN: r223021 --- gcc/ChangeLog | 13 +++++++++++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/class.c | 2 +- gcc/cp/method.c | 2 ++ gcc/cp/semantics.c | 1 + gcc/dwarf2out.c | 33 ++++++++++++++++++--------------- gcc/function.c | 2 +- gcc/tree.c | 27 ++++++++++++++++++--------- gcc/tree.def | 7 +++++-- 9 files changed, 66 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed176bdc256..d7d5ca01cfe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2015-05-11 Jan Hubicka + + * dwarf2out.c (gen_member_die): Sanity check that we access + TYPE_MAIN_VARIANT for TYPE_METHODS. + * function.c (use_register_for_decl): Look for TYPE_MAIN_VARIANT when + checking TYPE_METHODS. + * tree.c (free_lang_data_in_type): See TYPE_METHODS to error_mark_node + if non-null. + (build_distinct_type_copy): Clear TYPE_METHODS. + (verify_type_variant): Verify that TYPE_METHODS is NULL for variants. + (verify_type): Allow TYPE_METHODS to be error_mark_node. + * tree.def: Update docs of TYPE_STUB_DECL and TYPE_METHODS. + 2015-05-11 Eric Botcazou * emit-rtl.c (emit_pattern_after_setloc): Add missing guard. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fa7a1a0a4d2..0bdbf3c4c1c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-05-11 Jan Hubicka + + * class.c (fixup_type_variants): Do not copy TYPE_METHODS + (one_inheriting_sig): Assert tat we always set TYPE_METHODS of main variant. + * semantics.c (finish_member_declaration): Likewise. + * method.c (lazily_declare_fn): Allways add method to main variant list. + 2015-05-09 Aldy Hernandez PR bootstrap/66085 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c1548a0ae16..41607055493 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1972,7 +1972,6 @@ fixup_type_variants (tree t) /* Copy whatever these are holding today. */ TYPE_VFIELD (variants) = TYPE_VFIELD (t); - TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t); } } @@ -3238,6 +3237,7 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms) parmlist = tree_cons (NULL_TREE, parms[i], parmlist); tree fn = implicitly_declare_fn (sfk_inheriting_constructor, t, false, ctor, parmlist); + gcc_assert (TYPE_MAIN_VARIANT (t) == t); if (add_method (t, fn, NULL_TREE)) { DECL_CHAIN (fn) = TYPE_METHODS (t); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 81f50e6e23f..d41e1125aaa 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -2139,6 +2139,8 @@ lazily_declare_fn (special_function_kind sfk, tree type) /* Whether or not the argument has a const reference type. */ bool const_p = false; + type = TYPE_MAIN_VARIANT (type); + switch (sfk) { case sfk_constructor: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 701a8ebf18f..e1d18fb9f3d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2913,6 +2913,7 @@ finish_member_declaration (tree decl) CLASSTYPE_METHOD_VEC. */ if (add_method (current_class_type, decl, NULL_TREE)) { + gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == current_class_type); DECL_CHAIN (decl) = TYPE_METHODS (current_class_type); TYPE_METHODS (current_class_type) = decl; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index a1394efd3d3..3212c2e845d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -19945,23 +19945,26 @@ gen_member_die (tree type, dw_die_ref context_die) gen_decl_die (member, NULL, context_die); } + /* We do not keep type methods in type variants. */ + gcc_assert (TYPE_MAIN_VARIANT (type) == type); /* Now output info about the function members (if any). */ - for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member)) - { - /* Don't include clones in the member list. */ - if (DECL_ABSTRACT_ORIGIN (member)) - continue; - /* Nor constructors for anonymous classes. */ - if (DECL_ARTIFICIAL (member) - && dwarf2_name (member, 0) == NULL) - continue; + if (TYPE_METHODS (type) != error_mark_node) + for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member)) + { + /* Don't include clones in the member list. */ + if (DECL_ABSTRACT_ORIGIN (member)) + continue; + /* Nor constructors for anonymous classes. */ + if (DECL_ARTIFICIAL (member) + && dwarf2_name (member, 0) == NULL) + continue; - child = lookup_decl_die (member); - if (child) - splice_child_die (context_die, child); - else - gen_decl_die (member, NULL, context_die); - } + child = lookup_decl_die (member); + if (child) + splice_child_die (context_die, child); + else + gen_decl_die (member, NULL, context_die); + } } /* Generate a DIE for a structure or union type. If TYPE_DECL_SUPPRESS_DEBUG diff --git a/gcc/function.c b/gcc/function.c index 4f4c461943b..42d5aebd418 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2170,7 +2170,7 @@ use_register_for_decl (const_tree decl) /* When not optimizing, disregard register keyword for variables with types containing methods, otherwise the methods won't be callable from the debugger. */ - if (TYPE_METHODS (TREE_TYPE (decl))) + if (TYPE_METHODS (TYPE_MAIN_VARIANT (TREE_TYPE (decl)))) return false; break; default: diff --git a/gcc/tree.c b/gcc/tree.c index 0c97667b6a0..97e84eb7409 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5100,7 +5100,13 @@ free_lang_data_in_type (tree type) if (TYPE_VFIELD (type) && TREE_CODE (TYPE_VFIELD (type)) != FIELD_DECL) TYPE_VFIELD (type) = NULL_TREE; - TYPE_METHODS (type) = NULL_TREE; + /* Remove TYPE_METHODS list. While it would be nice to keep it + to enable ODR warnings about different method lists, doing so + seems to impractically increase size of LTO data streamed. + Keep the infrmation if TYPE_METHODS was non-NULL. This is used + by function.c and pretty printers. */ + if (TYPE_METHODS (type)) + TYPE_METHODS (type) = error_mark_node; if (TYPE_BINFO (type)) { free_lang_data_in_binfo (TYPE_BINFO (type)); @@ -6574,6 +6580,12 @@ build_distinct_type_copy (tree type) TYPE_MAIN_VARIANT (t) = t; TYPE_NEXT_VARIANT (t) = 0; + /* We do not record methods in type copies nor variants + so we do not need to keep them up to date when new method + is inserted. */ + if (RECORD_OR_UNION_TYPE_P (t)) + TYPE_METHODS (t) = NULL_TREE; + /* Note that it is now possible for TYPE_MIN_VALUE to be a value whose TREE_TYPE is not t. This can also happen in the Ada frontend when using subtypes. */ @@ -12528,13 +12540,9 @@ verify_type_variant (const_tree t, tree tv) debug_tree (tv); return false; } - /* FIXME: this check triggers during libstdc++ build that is a bug. - It affects non-LTO debug output only, because free_lang_data clears - this anyway. */ - if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0 - && TYPE_METHODS (t) != TYPE_METHODS (tv)) + if (RECORD_OR_UNION_TYPE_P (t) && TYPE_METHODS (t)) { - error ("type variant has different TYPE_METHODS"); + error ("type variant has TYPE_METHODS"); debug_tree (tv); return false; } @@ -12749,9 +12757,10 @@ verify_type (const_tree t) if (RECORD_OR_UNION_TYPE_P (t)) { if (TYPE_METHODS (t) && TREE_CODE (TYPE_METHODS (t)) != FUNCTION_DECL - && TREE_CODE (TYPE_METHODS (t)) != TEMPLATE_DECL) + && TREE_CODE (TYPE_METHODS (t)) != TEMPLATE_DECL + && TYPE_METHODS (t) != error_mark_node) { - error ("TYPE_METHODS is not FUNCTION_DECL nor TEMPLATE_DECL"); + error ("TYPE_METHODS is not FUNCTION_DECL, TEMPLATE_DECL nor error_mark_node"); debug_tree (TYPE_METHODS (t)); error_found = true; } diff --git a/gcc/tree.def b/gcc/tree.def index ea7bea046d6..56580af664c 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -110,9 +110,12 @@ DEFTREECODE (BLOCK, "block", tcc_exceptional, 0) particular, since any type which is of some type category (e.g. an array type or a function type) which cannot either have a name itself or have named members doesn't really have a "scope" per se. - The TREE_CHAIN field is used as a forward-references to names for + The TYPE_STUB_DECL field is used as a forward-references to names for ENUMERAL_TYPE, RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE nodes; - see below. */ + see below. + The TYPE_METHODS points to list of all methods associated with the type. + It is non-NULL only at main variant of the type and after free_lang_data + it may be set to error_mark_node instead of actual list to save memory. */ /* The ordering of the following codes is optimized for the checking macros in tree.h. Changing the order will degrade the speed of the -- 2.30.2