We were wrongly considering two classes in anonymous namespaces in
different files to be the same class due to string comparison. We have
a way to avoid that, by putting a '*' at the beginning of the typeinfo
name, but weren't doing that in this case because TREE_PUBLIC was
wrongly set on the typeinfo by set_linkage_according_to_type. Rather
than try to fix that function, we should just use determine_visibility,
which already gets this stuff right.
While looking at this, I also noticed that we were adopting a tentative
alias as first_global_object_name because its linkage flags hadn't been
set properly yet.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 5576725d9e58e9201695756f6cd228199e3ea724
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Jun 22 23:39:42 2011 -0400
PR c++/49440
* class.c (set_linkage_according_to_type): Just check TREE_PUBLIC
on the type's name.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 09444fb..9e387a6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -677,21 +677,10 @@ get_vtable_name (tree type)
the abstract. */
void
-set_linkage_according_to_type (tree type, tree decl)
+set_linkage_according_to_type (tree type ATTRIBUTE_UNUSED, tree decl)
{
- /* If TYPE involves a local class in a function with internal
- linkage, then DECL should have internal linkage too. Other local
- classes have no linkage -- but if their containing functions
- have external linkage, it makes sense for DECL to have external
- linkage too. That will allow template definitions to be merged,
- for example. */
- if (no_linkage_check (type, /*relaxed_p=*/true))
- {
- TREE_PUBLIC (decl) = 0;
- DECL_INTERFACE_KNOWN (decl) = 1;
- }
- else
- TREE_PUBLIC (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ determine_visibility (decl);
}
/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
diff --git a/gcc/testsuite/g++.dg/rtti/anon-ns1.C b/gcc/testsuite/g++.dg/rtti/anon-ns1.C
new file mode 100644
index 0000000..fd6f8af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/anon-ns1.C
@@ -0,0 +1,15 @@
+// PR c++/49440
+// The typeinfo name for A should start with * so we compare
+// it by address rather than contents.
+
+// { dg-final { scan-assembler "\"\*N\[^\"\]+1AE\"" } }
+
+namespace
+{
+ class A { };
+}
+
+void f()
+{
+ throw A();
+}
commit d567cac789228a15f7ce98350e19a7b4c52429ab
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Jun 22 23:40:07 2011 -0400
* optimize.c (maybe_clone_body): Set linkage flags before
cgraph_same_body_alias.
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 87302dc..b9e3551 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -310,8 +310,11 @@ maybe_clone_body (tree fn)
|| (HAVE_COMDAT_GROUP
&& DECL_WEAK (fns[0])))
&& (flag_syntax_only
- || cgraph_same_body_alias (cgraph_get_node (fns[0]), clone,
- fns[0])))
+ /* Set linkage flags appropriately before
+ cgraph_create_function_alias looks at them. */
+ || (expand_or_defer_fn_1 (clone)
+ && cgraph_same_body_alias (cgraph_get_node (fns[0]),
+ clone, fns[0]))))
{
alias = true;
if (DECL_ONE_ONLY (fns[0]))