diff options
author | Jason Merrill <jason@redhat.com> | 2007-09-29 22:41:39 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2007-09-29 22:41:39 -0400 |
commit | dc472c59a52d068c37cb0c14e94564da8729f232 (patch) | |
tree | f1cf66738af3f8ec706bba8578e57a6acd9d6444 | |
parent | 38b1c01c84ae8dfe52175cf11fce0534c8643af9 (diff) | |
download | gcc-dc472c59a52d068c37cb0c14e94564da8729f232.zip gcc-dc472c59a52d068c37cb0c14e94564da8729f232.tar.gz gcc-dc472c59a52d068c37cb0c14e94564da8729f232.tar.bz2 |
re PR c++/33094 (ICE on valid C++ virtual template static member in anonymous namespace)
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.
From-SVN: r128890
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/visibility/anon6.C | 28 |
5 files changed, 43 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5827a57..5609f1a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-09-29 Jason Merrill <jason@redhat.com> + + 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 <aaw@google.com> Revert diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f28e965..bd9292a 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 b898a02..469e6b8 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 c00c979..ce5e528 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 0000000..951de49 --- /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<int>::c is emitted as an internal symbol, and C<int>::c is +// not emitted. + +namespace +{ + template <typename T> + class A + { + virtual T f1() { return c; } + static const T c = 0; + }; + + template <typename T> + class B + { + static const T c = 0; + }; + + template <typename T> const T B<T>::c; + + template class A<int>; + template class B<int>; +} |