This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Fix C++ constructor regression


Unfortunately, one of my patches for initialization priority included
an overly agressive cleanup of the C++ front end.  In particular, on
targets without .ctors/.dtors support at all (never mind priority
support), my changes made us stop generating the global initialization
functions identified by collect2, munch, etc. required to run the
constructors.

This patch moves more of the C front end support into common code, and
then uses that from the C++ front end, to fix that regression, rather
than reverting the earlier C++ changes per se.

Barring any regressions, this completes the initialization-priority
changes.

Tested on x86_64-unknown-linux-gnu, applied to mainline.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2007-02-26  Mark Mitchell  <mark@codesourcery.com>

	* c-decl.c (static_ctors): Move to c-common.c.
	(static_dtors): Likewise.
	(finish_function): Use c_record_cdtor_fn.
	(build_cdtor): Move to c-common.c.
	(c_write_global_declarations): Use c_build_cdtor_fns.
	* c-common.h (static_ctors): Declare.
	(static_dtors): Likewise.
	(c_record_cdtor_fn): Likewise.
	(c_build_cdtor_fns): Likewise.
	* c-common.c (static_ctors): New variable.
	(static_dtors): Likewise.
	(c_record_cdtor_fn): New function.
	(build_cdtor): Move from c-decl.c
	(c_build_cdtor_fns): New function.

2007-02-26  Mark Mitchell  <mark@codesourcery.com>

	* semantics.c (expand_or_defer_fn): Call c_record_cdtor_fn.
	* decl2.c (cp_write_gloabl_declarations): Call c_build_cdtor_fns.

Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 122334)
+++ gcc/c-decl.c	(working copy)
@@ -411,11 +411,6 @@ static bool keep_next_level_flag;
 
 static bool next_is_function_body;
 
-/* Functions called automatically at the beginning and end of execution.  */
-
-static GTY(()) tree static_ctors;
-static GTY(()) tree static_dtors;
-
 /* Forward declarations.  */
 static tree lookup_name_in_scope (tree, struct c_scope *);
 static tree c_make_fname_decl (tree, int);
@@ -6776,14 +6771,9 @@ finish_function (void)
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
 
-  /* If we don't have ctors/dtors sections, and this is a static
-     constructor or destructor, it must be recorded now.  */
-  if (DECL_STATIC_CONSTRUCTOR (fndecl)
-      && !targetm.have_ctors_dtors)
-    static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
-  if (DECL_STATIC_DESTRUCTOR (fndecl)
-      && !targetm.have_ctors_dtors)
-    static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+  /* Keep track of functions declared with the "constructor" and
+     "destructor" attribute.  */
+  c_record_cdtor_fn (fndecl);
 
   /* Finalize the ELF visibility for the function.  */
   c_determine_visibility (fndecl);
@@ -7812,24 +7802,6 @@ finish_declspecs (struct c_declspecs *sp
   return specs;
 }
 
-/* Synthesize a function which calls all the global ctors or global
-   dtors in this file.  This is only used for targets which do not
-   support .ctors/.dtors sections.  FIXME: Migrate into cgraph.  */
-static void
-build_cdtor (int method_type, tree cdtors)
-{
-  tree body = 0;
-
-  if (!cdtors)
-    return;
-
-  for (; cdtors; cdtors = TREE_CHAIN (cdtors))
-    append_to_statement_list (build_function_call (TREE_VALUE (cdtors), 0),
-			      &body);
-
-  cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
-}
-
 /* A subroutine of c_write_global_declarations.  Perform final processing
    on one file scope's declarations (or the external scope's declarations),
    GLOBALS.  */
@@ -7923,11 +7895,9 @@ c_write_global_declarations (void)
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
   c_write_global_declarations_1 (BLOCK_VARS (ext_block));
 
-  /* Generate functions to call static constructors and destructors
-     for targets that do not support .ctors/.dtors sections.  These
-     functions have magic names which are detected by collect2.  */
-  build_cdtor ('I', static_ctors); static_ctors = 0;
-  build_cdtor ('D', static_dtors); static_dtors = 0;
+  /* Call functions declared with the "constructor" or "destructor"
+     attribute.  */
+  c_build_cdtor_fns ();
 
   /* We're done parsing; proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 122335)
+++ gcc/c-common.c	(working copy)
@@ -663,6 +663,11 @@ const struct attribute_spec c_common_for
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
+/* Functions called automatically at the beginning and end of execution.  */
+
+tree static_ctors;
+tree static_dtors;
+
 /* Push current bindings for the function name VAR_DECLS.  */
 
 void
@@ -6875,4 +6880,59 @@ warn_for_unused_label (tree label)
     }
 }
 
+/* If FNDECL is a static constructor or destructor, add it to the list
+   of functions to be called by the file scope initialization
+   function.  */
+
+void
+c_record_cdtor_fn (tree fndecl)
+{
+  if (targetm.have_ctors_dtors)
+    return;
+
+  if (DECL_STATIC_CONSTRUCTOR (fndecl))
+    static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+  if (DECL_STATIC_DESTRUCTOR (fndecl))
+    static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+}
+
+/* Synthesize a function which calls all the global ctors or global
+   dtors in this file.  This is only used for targets which do not
+   support .ctors/.dtors sections.  FIXME: Migrate into cgraph.  */
+static void
+build_cdtor (int method_type, tree cdtors)
+{
+  tree body = 0;
+
+  if (!cdtors)
+    return;
+
+  for (; cdtors; cdtors = TREE_CHAIN (cdtors))
+    append_to_statement_list (build_function_call (TREE_VALUE (cdtors), 0),
+			      &body);
+
+  cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
+}
+
+/* Generate functions to call static constructors and destructors
+   for targets that do not support .ctors/.dtors sections.  These
+   functions have magic names which are detected by collect2.  */
+
+void
+c_build_cdtor_fns (void)
+{
+  if (!targetm.have_ctors_dtors)
+    {
+      build_cdtor ('I', static_ctors); 
+      static_ctors = NULL_TREE;
+      build_cdtor ('D', static_dtors); 
+      static_dtors = NULL_TREE;
+    }
+  else
+    {
+      gcc_assert (!static_ctors);
+      gcc_assert (!static_dtors);
+    }
+}
+
 #include "gt-c-common.h"
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h	(revision 122334)
+++ gcc/c-common.h	(working copy)
@@ -988,4 +988,11 @@ extern tree c_omp_remap_decl (tree, bool
 #define GCC_DIAG_STYLE __gcc_cdiag__
 #endif
 
+/* Functions called automatically at the beginning and end of execution.  */
+extern GTY (()) tree static_ctors;
+extern GTY (()) tree static_dtors;
+
+extern void c_record_cdtor_fn (tree);
+extern void c_build_cdtor_fns (void);
+
 #endif /* ! GCC_C_COMMON_H */
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 122334)
+++ gcc/cp/semantics.c	(working copy)
@@ -3159,6 +3159,10 @@ expand_or_defer_fn (tree fn)
       return;
     }
 
+  /* Keep track of functions declared with the "constructor" and
+     "destructor" attribute.  */
+  c_record_cdtor_fn (fn);
+
   /* We make a decision about linkage for these functions at the end
      of the compilation.  Until that point, we do not want the back
      end to output them -- but we do want it to see the bodies of
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 122334)
+++ gcc/cp/decl2.c	(working copy)
@@ -3289,6 +3289,8 @@ cp_write_global_declarations (void)
   if (priority_info_map)
     splay_tree_delete (priority_info_map);
 
+  c_build_cdtor_fns ();
+
   /* Generate any missing aliases.  */
   maybe_apply_pending_pragma_weaks ();
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]