aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-05-12 00:24:33 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-05-11 22:24:33 +0000
commit5ce039dfe917d694bef1ecb16844f3b1bcb7ed09 (patch)
treeb27aa77b5c6f68e088a61128b1c06c597c6b36f9 /gcc
parent20d4397af8a085a17925d3a3a3545748d5ab7fc6 (diff)
downloadgcc-5ce039dfe917d694bef1ecb16844f3b1bcb7ed09.zip
gcc-5ce039dfe917d694bef1ecb16844f3b1bcb7ed09.tar.gz
gcc-5ce039dfe917d694bef1ecb16844f3b1bcb7ed09.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/dwarf2out.c33
-rw-r--r--gcc/function.c2
-rw-r--r--gcc/tree.c27
-rw-r--r--gcc/tree.def7
9 files changed, 66 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ed176bd..d7d5ca0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2015-05-11 Jan Hubicka <hubicka@ucw.cz>
+
+ * 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 <ebotcazou@adacore.com>
* emit-rtl.c (emit_pattern_after_setloc): Add missing guard.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fa7a1a0..0bdbf3c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2015-05-11 Jan Hubicka <hubicka@ucw.cz>
+
+ * 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 <aldyh@redhat.com>
PR bootstrap/66085
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c1548a0..4160705 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 81f50e6..d41e112 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 701a8eb..e1d18fb 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 a1394ef..3212c2e 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 4f4c461..42d5aeb 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 0c97667..97e84eb 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 ea7bea0..56580af 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