aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2018-08-21 12:36:37 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2018-08-21 10:36:37 +0000
commit143b379d89b12cccab345d3e424728b1b58af3e8 (patch)
tree2a44044d0c2f5470035f6f6380eaad8b5d809b43 /gcc/tree.c
parentdaa9715842345da5b9c440a9fef1ed3bc916bc18 (diff)
downloadgcc-143b379d89b12cccab345d3e424728b1b58af3e8.zip
gcc-143b379d89b12cccab345d3e424728b1b58af3e8.tar.gz
gcc-143b379d89b12cccab345d3e424728b1b58af3e8.tar.bz2
tree.c (free_lang_data_in_decl): Remove types from DECL_CONTEXT when possible.
* tree.c (free_lang_data_in_decl): Remove types from DECL_CONTEXT when possible. From-SVN: r263697
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index dd3439f..8d1e010 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5380,6 +5380,29 @@ free_lang_data_in_decl (tree decl)
nextp = &TREE_CHAIN (var);
}
}
+ /* We need to keep field decls associated with their trees. Otherwise tree
+ merging may merge some fileds and keep others disjoint wich in turn will
+ not do well with TREE_CHAIN pointers linking them.
+
+ Also do not drop containing types for virtual methods and tables because
+ these are needed by devirtualization. */
+ if (TREE_CODE (decl) != FIELD_DECL
+ && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
+ || !DECL_VIRTUAL_P (decl)))
+ {
+ tree ctx = DECL_CONTEXT (decl);
+ /* Variably modified types are needed for tree_is_indexable to decide
+ whether the type needs to go to local or global section.
+ This code is semi-broken but for now it is easiest to keep contexts
+ as expected. */
+ if (ctx && TYPE_P (ctx)
+ && !variably_modified_type_p (ctx, NULL_TREE))
+ {
+ while (ctx && TYPE_P (ctx))
+ ctx = TYPE_CONTEXT (ctx);
+ DECL_CONTEXT (decl) = ctx;
+ }
+ }
}