This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix decl_linkage for static data members and static member functions in anon namespace (PR c++/34213)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Mark Mitchell <mark at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 26 Nov 2007 08:37:02 -0500
- Subject: [C++ PATCH] Fix decl_linkage for static data members and static member functions in anon namespace (PR c++/34213)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Static data members or static member functions have DECL_THIS_STATIC set,
yet they have external linkage if the class they are contained within has.
Function-scope classes are already handled earlier, decl_function_context
returns true for them and so this code isn't hit. Unnamed classes can't
have static member functions or static data members, so I think
DECL_CLASS_CONTEXT is sufficient.
Regtested on x86_64-linux, ok for trunk?
2007-11-26 Jakub Jelinek <jakub@redhat.com>
PR c++/34213
* tree.c (decl_linkage): Static data members and static member
functions in anonymous ns classes are lk_external.
* g++.dg/ext/visibility/anon8.C: New test.
--- gcc/cp/tree.c.jj 2007-11-20 11:31:09.000000000 +0100
+++ gcc/cp/tree.c 2007-11-26 13:44:30.000000000 +0100
@@ -2526,10 +2526,18 @@ decl_linkage (tree decl)
/* Members of the anonymous namespace also have TREE_PUBLIC unset, but
are considered to have external linkage for language purposes. DECLs
really meant to have internal linkage have DECL_THIS_STATIC set. */
- if (TREE_CODE (decl) == TYPE_DECL
- || ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
- && !DECL_THIS_STATIC (decl)))
+ if (TREE_CODE (decl) == TYPE_DECL)
return lk_external;
+ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (!DECL_THIS_STATIC (decl))
+ return lk_external;
+
+ /* Static data members and static member functions from classes
+ in anonymous namespace also don't have TREE_PUBLIC set. */
+ if (DECL_CLASS_CONTEXT (decl))
+ return lk_external;
+ }
/* Everything else has internal linkage. */
return lk_internal;
--- gcc/testsuite/g++.dg/ext/visibility/anon8.C.jj 2007-11-26 13:48:44.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/visibility/anon8.C 2007-11-26 14:22:50.000000000 +0100
@@ -0,0 +1,33 @@
+// PR c++/34213
+// { dg-do compile }
+
+template <void (*fn) ()>
+void call ()
+{
+ fn ();
+}
+
+namespace
+{
+ struct B1
+ {
+ static void fn1 () {}
+ static void fn4 ();
+ };
+ void fn3 () {}
+ void B1::fn4 () {}
+ static void fn5 () {}
+}
+
+int main ()
+{
+ struct B2
+ {
+ static void fn2 () {}
+ };
+ call<&B1::fn1> ();
+ call<&B2::fn2> (); // { dg-error "not external linkage|no matching" }
+ call<&fn3> ();
+ call<&B1::fn4> ();
+ call<&fn5> (); // { dg-error "not external linkage|no matching" }
+}
Jakub