Patchwork C++ PATCH for c++/49440 (wrong tinfo comparison with anonymous namespaces)

login
register
mail settings
Submitter Jason Merrill
Date June 23, 2011, 4:51 p.m.
Message ID <4E036F00.4090608@redhat.com>
Download mbox | patch
Permalink /patch/101656/
State New
Headers show

Comments

Jason Merrill - June 23, 2011, 4:51 p.m.
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.

Patch

commit 5576725d9e58e9201695756f6cd228199e3ea724
Author: Jason Merrill <jason@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 <jason@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]))