This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH RFC: PR 33094: Test DECL_INITIAL in make_rtl_for_nonlocal_decl
- From: Jason Merrill <jason at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Ian Lance Taylor <iant at google dot com>, gcc-patches at gcc dot gnu dot org
- Date: Sat, 29 Sep 2007 22:40:23 -0400
- Subject: Re: PATCH RFC: PR 33094: Test DECL_INITIAL in make_rtl_for_nonlocal_decl
- References: <m3d4xmqj5c.fsf@localhost.localdomain> <46C63895.9040001@codesourcery.com> <46FD4C8A.3020707@redhat.com>
Since I'm about to go off to the C++ meeting, I've gone ahead and fixed
the crash by allowing !TREE_PUBLIC as well as DECL_EXTERN. And added a
test to make sure that we are emitting static member variables iff they
have an out-of-class definition.
Tested x86_64-pc-linux-gnu, applied to trunk. I'd like to apply this to
4.2 as well; OK, Mark?
2007-09-28 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.
Index: cp/decl.c
===================================================================
*** cp/decl.c (revision 128841)
--- cp/decl.c (working copy)
*************** make_rtl_for_nonlocal_decl (tree decl, t
*** 5092,5098 ****
/* 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));
}
/* We don't create any RTL for local variables. */
--- 5092,5098 ----
/* 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) || !TREE_PUBLIC (decl));
}
/* We don't create any RTL for local variables. */
Index: cp/cp-tree.h
===================================================================
*** cp/cp-tree.h (revision 128841)
--- cp/cp-tree.h (working copy)
*************** more_aggr_init_expr_args_p (const aggr_i
*** 3225,3231 ****
/* 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. */
#define DECL_NOT_REALLY_EXTERN(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern)
--- 3225,3235 ----
/* 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.
!
! 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)
Index: cp/decl2.c
===================================================================
*** cp/decl2.c (revision 128844)
--- cp/decl2.c (working copy)
*************** coerce_delete_type (tree type)
*** 1314,1319 ****
--- 1314,1322 ----
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)
{
Index: testsuite/g++.dg/ext/visibility/anon6.C
===================================================================
*** testsuite/g++.dg/ext/visibility/anon6.C (revision 0)
--- testsuite/g++.dg/ext/visibility/anon6.C (revision 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>;
+ }