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]

[lto][patch] Fix case where cc1plus writes a function_decl but not the cgraph node


This patch fixes the contained testcase.

In cc1plus we sometimes write a function_decl for which we don't have
a cgraph node. When reading the cgraphs in lto1, we might be forced to
create the node and must make sure that the file_data is properly
initialized. With this patch this is done by remembering the file_data
information in the same way we remember symbol resolution.

gcc/
2008-11-18  Rafael Espindola  <espindola@google.com>

	* lto-cgraph.c (input_edge): Initialize callee->local.lto_file_data if
	we have a new node.
	* lto-symtab.c (lto_symtab_decl_def): Add file_data field.
	(lto_symtab_set_resolution): Rename to
	lto_symtab_set_resolution_and_file_data. Record the file_data.
	(lto_symtab_merge_decl, lto_symtab_merge_fn): Add file_data argument.
	Update all uses.
	(lto_symtab_get_symtab_def): New.
	(lto_symtab_get_resolution): Use lto_symtab_get_symtab_def.
	(lto_symtab_get_file_data): New.
	* lto-tree-in.h (lto_symtab_merge_fn): Add file_data argument.
	Update all uses.
	(lto_symtab_get_file_data): New.

gcc/testsuite
2008-11-18  Rafael Espindola  <espindola@google.com>
	* gcc.dg/lto/20081118_0.C (new)
	* gcc.dg/lto/20081118_1.C (new)

Cheers,
-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 536fde1..90461db 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -647,12 +647,23 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
 
   if (prevailing_callee != callee->decl)
     {
+      struct lto_file_decl_data *file_data;
+
       /* We cannot replace a clone! */
       gcc_assert (callee == cgraph_node (callee->decl));
 
 
       callee = cgraph_node (prevailing_callee);
       gcc_assert (callee);
+
+      /* If LGEN (cc1 or cc1plus) had nothing to do with the node,
+	 it might not have created it. In this case, we just created a new
+	 node in the above call to cgraph_node. Mark the file it came from. */
+      file_data = lto_symtab_get_file_data (prevailing_callee);
+      if (callee->local.lto_file_data)
+	gcc_assert (callee->local.lto_file_data == file_data);
+      else
+	callee->local.lto_file_data = file_data;
     }
 
   edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
diff --git a/gcc/lto-function-in.c b/gcc/lto-function-in.c
index 122cbf0..5e359b3 100644
--- a/gcc/lto-function-in.c
+++ b/gcc/lto-function-in.c
@@ -2930,7 +2930,7 @@ input_function_decl (struct lto_input_block *ib, struct data_in *data_in)
     {
       enum ld_plugin_symbol_resolution resolution;
       resolution = get_resolution (data_in, index);
-      lto_symtab_merge_fn (decl, resolution);
+      lto_symtab_merge_fn (decl, resolution, data_in->file_data);
     }
 
   LTO_DEBUG_TOKEN ("end_function_decl");
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 75024bd..225a154 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -53,6 +53,7 @@ struct lto_symtab_decl_def GTY (())
 {
   struct lto_symtab_base_def base;
   enum ld_plugin_symbol_resolution resolution;
+  struct lto_file_decl_data * GTY((skip (""))) file_data;
 };
 typedef struct lto_symtab_decl_def *lto_symtab_decl_t;
 
@@ -554,7 +555,10 @@ lto_symtab_compatible (tree old_decl, tree new_decl)
 /* Marks decl DECL as having resolution RESOLUTION. */
 
 static void
-lto_symtab_set_resolution (tree decl, ld_plugin_symbol_resolution_t resolution)
+lto_symtab_set_resolution_and_file_data (tree decl,
+					 ld_plugin_symbol_resolution_t
+					 resolution,
+					 struct lto_file_decl_data *file_data)
 {
   lto_symtab_decl_t new_entry;
   void **slot;
@@ -567,6 +571,7 @@ lto_symtab_set_resolution (tree decl, ld_plugin_symbol_resolution_t resolution)
   new_entry = GGC_CNEW (struct lto_symtab_decl_def);
   new_entry->base.node = decl;
   new_entry->resolution = resolution;
+  new_entry->file_data = file_data;
   
   lto_symtab_maybe_init_hash_tables ();
   slot = htab_find_slot (lto_symtab_decls, new_entry, INSERT);
@@ -630,7 +635,8 @@ lto_symtab_set_identifier_decl (tree id, tree decl)
 
 static void
 lto_symtab_merge_decl (tree new_decl,
-		       enum ld_plugin_symbol_resolution resolution)
+		       enum ld_plugin_symbol_resolution resolution,
+		       struct lto_file_decl_data *file_data)
 {
   tree old_decl;
   tree name;
@@ -657,7 +663,7 @@ lto_symtab_merge_decl (tree new_decl,
     }
 
   /* Remember the resolution of this symbol. */
-  lto_symtab_set_resolution (new_decl, resolution);
+  lto_symtab_set_resolution_and_file_data (new_decl, resolution, file_data);
 
   /* Retrieve the previous declaration.  */
   name = DECL_ASSEMBLER_NAME (new_decl);
@@ -721,16 +727,17 @@ lto_symtab_merge_decl (tree new_decl,
 void
 lto_symtab_merge_var (tree new_var, enum ld_plugin_symbol_resolution resolution)
 {
-  lto_symtab_merge_decl (new_var, resolution);
+  lto_symtab_merge_decl (new_var, resolution, NULL);
 }
 
 /* Merge the FUNCTION_DECL NEW_FN with resolution RESOLUTION with any previous
    declaration with the same name. */
 
 void
-lto_symtab_merge_fn (tree new_fn, enum ld_plugin_symbol_resolution resolution)
+lto_symtab_merge_fn (tree new_fn, enum ld_plugin_symbol_resolution resolution,
+		     struct lto_file_decl_data *file_data)
 {
-  lto_symtab_merge_decl (new_fn, resolution);
+  lto_symtab_merge_decl (new_fn, resolution, file_data);
 }
 
 /* Given the decl DECL, return the prevailing decl with the same name. */
@@ -753,29 +760,47 @@ lto_symtab_prevailing_decl (tree decl)
   return ret;
 }
 
+/* Return the hash table entry of DECL. */
+
+static struct lto_symtab_decl_def *
+lto_symtab_get_symtab_def (tree decl)
+{
+  struct lto_symtab_decl_def temp, *symtab_decl;
+  void **slot;
+
+  gcc_assert (decl);
+
+  lto_symtab_maybe_init_hash_tables ();
+  temp.base.node = decl;
+  slot = htab_find_slot (lto_symtab_decls, &temp, NO_INSERT);
+  gcc_assert (slot && *slot);
+  symtab_decl = (struct lto_symtab_decl_def*) *slot;
+  return symtab_decl;
+}
+
 /* Return the resolution of DECL. */
 
 enum ld_plugin_symbol_resolution
 lto_symtab_get_resolution (tree decl)
 {
-  struct lto_symtab_decl_def temp, *symtab_decl;
-  void **slot;
- 
   gcc_assert (decl);
 
   if (!TREE_PUBLIC (decl))
     return LDPR_PREVAILING_DEF_IRONLY;
 
   /* FIXME lto: There should be no DECL_ABSTRACT in the middle end. */
- if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT (decl))
-   return LDPR_PREVAILING_DEF_IRONLY;
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT (decl))
+    return LDPR_PREVAILING_DEF_IRONLY;
 
- lto_symtab_maybe_init_hash_tables ();
- temp.base.node = decl;
- slot = htab_find_slot (lto_symtab_decls, &temp, NO_INSERT);
- gcc_assert (slot && *slot);
- symtab_decl = (struct lto_symtab_decl_def*) *slot;
- return symtab_decl->resolution;
+  return lto_symtab_get_symtab_def(decl)->resolution;
+}
+
+/* Return the file of DECL. */
+
+struct lto_file_decl_data *
+lto_symtab_get_file_data (tree decl)
+{
+  return lto_symtab_get_symtab_def(decl)->file_data;
 }
 
 /* Remove any storage used to store resolution of DECL.  */
diff --git a/gcc/lto-tree-in.h b/gcc/lto-tree-in.h
index a5ace51..d92ca57 100644
--- a/gcc/lto-tree-in.h
+++ b/gcc/lto-tree-in.h
@@ -115,10 +115,12 @@ extern void lto_symtab_merge_var (tree new_var,
 
 /* Like lto_symtab_merge_var, but for functions.  */
 extern void lto_symtab_merge_fn (tree new_fn,
-                                 enum ld_plugin_symbol_resolution resolution);
+                                 enum ld_plugin_symbol_resolution resolution,
+                                 struct lto_file_decl_data *file_data);
 
 extern tree lto_symtab_prevailing_decl (tree decl);
 extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
+struct lto_file_decl_data *lto_symtab_get_file_data (tree decl);
 extern void lto_symtab_clear_resolution (tree decl);
 
 #endif  /* GCC_LTO_TREE_IN_H  */
diff --git a/gcc/testsuite/gcc.dg/lto/20081118_0.C b/gcc/testsuite/gcc.dg/lto/20081118_0.C
new file mode 100644
index 0000000..04cca51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20081118_0.C
@@ -0,0 +1,8 @@
+class C {
+ public:
+  virtual ~C();
+  virtual void foo();
+};
+void bar() {
+  new C();
+}
diff --git a/gcc/testsuite/gcc.dg/lto/20081118_1.C b/gcc/testsuite/gcc.dg/lto/20081118_1.C
new file mode 100644
index 0000000..7ed4eeb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20081118_1.C
@@ -0,0 +1,11 @@
+class C {
+ public:
+  virtual ~C();
+  virtual void foo();
+};
+class D  {
+  ~D();
+  C lexer_;
+};
+D::~D() {
+}

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