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