diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5827a57964e..5609f1a1626 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-09-29 Jason Merrill + + PR c++/33094 + * decl.c (make_rtl_for_nonlocal_decl): It's ok for a member + constant to not have DECL_EXTERNAL if it's file-local. + 2007-09-28 Ollie Wild Revert diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f28e965465f..bd9292a5565 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3225,7 +3225,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) /* DECL_EXTERNAL must be set on a decl until the decl is actually emitted, so that assemble_external will work properly. So we have this flag to - tell us whether the decl is really not external. */ + tell us whether the decl is really not external. + + This flag does not indicate whether or not the decl is defined in the + current translation unit; it indicates whether or not we should emit the + decl at the end of compilation if it is defined and needed. */ #define DECL_NOT_REALLY_EXTERN(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b898a02d970..469e6b836ee 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5092,7 +5092,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) /* An in-class declaration of a static data member should be external; it is only a declaration, and not a definition. */ if (init == NULL_TREE) - gcc_assert (DECL_EXTERNAL (decl)); + gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)); } /* We don't create any RTL for local variables. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index c00c9796a1e..ce5e52816ed 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1314,6 +1314,9 @@ coerce_delete_type (tree type) return type; } +/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable + and mark them as needed. */ + static void mark_vtable_entries (tree decl) { diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon6.C b/gcc/testsuite/g++.dg/ext/visibility/anon6.C new file mode 100644 index 00000000000..951de4964e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon6.C @@ -0,0 +1,28 @@ +// PR c++/33094 +// { dg-final { scan-assembler "1BIiE1cE" } } +// { dg-final { scan-assembler-not "globl.*1BIiE1cE" } } +// { dg-final { scan-assembler-not "1CIiE1cE" } } + +// Test that B::c is emitted as an internal symbol, and C::c is +// not emitted. + +namespace +{ + template + class A + { + virtual T f1() { return c; } + static const T c = 0; + }; + + template + class B + { + static const T c = 0; + }; + + template const T B::c; + + template class A; + template class B; +}