Tested x86_64-pc-linux-gnu. Does this look good, or do we want to
factor the
flag clearing into a symtab_node counterpart to cgraph_node::reset?
-- 8< --
In 107897, by the time we are looking at the mangling clash, the
alias has already been removed from the symbol table by
analyze_functions,
so we can't look at n->cpp_implicit_alias. So just assume that it's an
alias if it's internal.
In 108887 the problem is that removing the mangling alias from the
symbol
table confuses analyze_functions, because it ended up as first_analyzed
somehow, so it becomes a dangling pointer. Fixed by clearing
various flags
to neutralize the alias.
PR c++/107897
PR c++/108887
gcc/cp/ChangeLog:
* decl2.cc (record_mangling): Improve symbol table handling.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-lambda3.C: Use -flto if supported.
* g++.dg/cpp0x/lambda/lambda-mangle7.C: New test.
---
gcc/cp/decl2.cc | 25 +++++--
.../g++.dg/cpp0x/lambda/lambda-mangle7.C | 70
+++++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/concepts-lambda3.C | 1 +
3 files changed, 91 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle7.C
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 387e24542cd..e6e58b08de4 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -4742,15 +4742,30 @@ record_mangling (tree decl, bool need_warning)
= mangled_decls->find_slot_with_hash (id,
IDENTIFIER_HASH_VALUE (id),
INSERT);
- /* If this is already an alias, remove the alias, because the real
+ /* If this is already an alias, cancel the alias, because the real
decl takes precedence. */
if (*slot && DECL_ARTIFICIAL (*slot) && DECL_IGNORED_P (*slot))
- if (symtab_node *n = symtab_node::get (*slot))
- if (n->cpp_implicit_alias)
+ {
+ if (symtab_node *n = symtab_node::get (*slot))
{
- n->remove ();
- *slot = NULL_TREE;
+ if (n->cpp_implicit_alias)
+ {
+ /* Actually removing the node isn't safe if other code is
already
+ holding a pointer to it, so just neutralize it. */
+ n->remove_from_same_comdat_group ();
+ n->analyzed = false;
+ n->definition = false;
+ n->alias = false;
+ n->cpp_implicit_alias = false;