C++ PATCH: Local statics
Mark Mitchell
mark@codesourcery.com
Sun Jul 23 13:00:00 GMT 2000
Jason Merill found a crash with the attached test case. I took the
opportunity to clean up some ugliness in our handling of static
variables; the resulting code is considerably cleaner.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-07-23 Mark Mitchell <mark@codesourcery.com>
* c-semantics.c (make_rtl_for_local_static): Use TREE_ASM_WRITTEN
to figure out whether or not a variable has already been emitted.
2000-07-23 Mark Mitchell <mark@codesourcery.com>
* decl.c (make_rtl_for_nonlocal_decl): Rework.
Index: testsuite/g++.old-deja/g++.other/static12.C
===================================================================
RCS file: static12.C
diff -N static12.C
*** /dev/null Tue May 5 13:32:27 1998
--- static12.C Sun Jul 23 12:49:48 2000
***************
*** 0 ****
--- 1,8 ----
+ // Build don't link:
+ // Origin: Jason Merrill <jason@redhat.com>
+
+ int main ()
+ {
+ static const int n = 10;
+ static const int *p = &n;
+ }
Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-semantics.c,v
retrieving revision 1.3
diff -c -p -r1.3 c-semantics.c
*** c-semantics.c 2000/07/10 10:56:21 1.3
--- c-semantics.c 2000/07/23 19:49:27
*************** make_rtl_for_local_static (decl)
*** 96,102 ****
/* If we inlined this variable, we could see it's declaration
again. */
! if (DECL_RTL (decl))
return;
if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
--- 96,102 ----
/* If we inlined this variable, we could see it's declaration
again. */
! if (TREE_ASM_WRITTEN (decl))
return;
if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.657
diff -c -p -r1.657 decl.c
*** decl.c 2000/07/21 06:41:38 1.657
--- decl.c 2000/07/23 19:49:40
*************** make_rtl_for_nonlocal_decl (decl, init,
*** 7825,7836 ****
tree init;
const char *asmspec;
{
! int toplev;
! tree type;
- type = TREE_TYPE (decl);
- toplev = toplevel_bindings_p ();
-
/* Handle non-variables up front. */
if (TREE_CODE (decl) != VAR_DECL)
{
--- 7825,7833 ----
tree init;
const char *asmspec;
{
! int toplev = toplevel_bindings_p ();
! int defer_p;
/* Handle non-variables up front. */
if (TREE_CODE (decl) != VAR_DECL)
{
*************** make_rtl_for_nonlocal_decl (decl, init,
*** 7838,7891 ****
return;
}
/* Set the DECL_ASSEMBLER_NAME for the variable. */
if (asmspec)
DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
! if (DECL_VIRTUAL_P (decl))
! make_decl_rtl (decl, NULL_PTR, toplev);
! else if (TREE_READONLY (decl)
! && DECL_INITIAL (decl) != NULL_TREE
! && DECL_INITIAL (decl) != error_mark_node
! && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
{
! DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
!
! if (toplev && ! TREE_PUBLIC (decl))
{
! /* If this is a static const, change its apparent linkage
! if it belongs to a #pragma interface. */
! if (!interface_unknown)
! {
! TREE_PUBLIC (decl) = 1;
! DECL_EXTERNAL (decl) = interface_only;
! }
! make_decl_rtl (decl, asmspec, toplev);
}
- else if (toplev)
- rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
- }
- else if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
- {
- my_friendly_assert (TREE_STATIC (decl), 19990828);
! if (init == NULL_TREE
! #ifdef DEFAULT_STATIC_DEFS
! /* If this code is dead, then users must
! explicitly declare static member variables
! outside the class def'n as well. */
! && TYPE_NEEDS_CONSTRUCTING (type)
! #endif
! )
! {
! DECL_EXTERNAL (decl) = 1;
! make_decl_rtl (decl, asmspec, 1);
! }
! else
! rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
}
! else if (TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL
! || (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)))
rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
}
--- 7835,7889 ----
return;
}
+ /* If we see a class member here, it should be a static data
+ member. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
+ {
+ my_friendly_assert (TREE_STATIC (decl), 19990828);
+ /* 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)
+ my_friendly_assert (DECL_EXTERNAL (decl), 20000723);
+ }
+
/* Set the DECL_ASSEMBLER_NAME for the variable. */
if (asmspec)
DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
! /* We don't create any RTL for local variables. */
! if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
! return;
!
! /* We defer emission of local statics until the corresponding
! DECL_STMT is expanded. */
! defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
!
! /* We try to defer namespace-scope static constants so that they are
! not emitted into the object file unncessarily. */
! if (!DECL_VIRTUAL_P (decl)
! && TREE_READONLY (decl)
! && DECL_INITIAL (decl) != NULL_TREE
! && DECL_INITIAL (decl) != error_mark_node
! && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
! && toplev
! && !TREE_PUBLIC (decl))
{
! /* Fool with the linkage according to #pragma interface. */
! if (!interface_unknown)
{
! TREE_PUBLIC (decl) = 1;
! DECL_EXTERNAL (decl) = interface_only;
}
! defer_p = 1;
}
!
! /* If we're deferring the variable, just make RTL. Do not actually
! emit the variable. */
! if (defer_p)
! make_decl_rtl (decl, asmspec, toplev);
! /* If we're not deferring, go ahead and assemble the variable. */
! else
rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
}
More information about the Gcc-patches
mailing list