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] Fix splitting of alias pairs


When streaming out alias pairs, we were emitting some pairs in
LTRANS files where those nodes weren't present.  This would
trigger the error:

'<symbol1>' aliased to undefined symbol '<symbol2>'

in finish_aliases_1.  Fixed by only streaming function aliases
together with the original cgraph nodes.  As a follow up, I'll
wrap alias_pairs in varasm.c with a couple of accessor functions.

Tested on x86_64.


Diego.

2008-12-19  Diego Novillo  <dnovillo@google.com>

	* lto-function-out.c (output_function): Tidy formatting.
	(output_constructors_and_inits): Only emit alias_pairs
	for FUNCTION_DECLs whose node is in SET.

testsuite/ChangeLog.lto:

2008-12-19  Rafael Avila de Espindola  <espindola@google.com>

	* g++.dg/lto/20081219_0.C: New.
	* g++.dg/lto/20081219_1.C: New.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 142823)
+++ lto-function-out.c	(working copy)
@@ -2186,7 +2186,7 @@ static int function_num;
 /* Output FN.  */
 
 static void
-output_function (struct cgraph_node* node)
+output_function (struct cgraph_node *node)
 {
   tree function = node->decl;
   struct function *fn = DECL_STRUCT_FUNCTION (function);
@@ -2404,11 +2404,31 @@ output_constructors_and_inits (cgraph_no
   /* The terminator for the constructor.  */
   output_zero (ob);
 
+  /* Emit the alias pairs for the nodes in SET.  */
   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
     {
-      output_expr_operand (ob, p->decl);
-      LTO_DEBUG_TOKEN ("alias_target");
-      output_expr_operand (ob, p->target);
+      bool output_p = false;
+
+      /* We only output the alias set for VAR_DECLs and FUNCTION_DECLs
+	 whose cgraph node is in SET.  This prevents problems when
+	 finalizing aliases during LTRANS (where the alias ends up
+	 referring to a function undefined in this file.  */
+      if (TREE_CODE (p->decl) == VAR_DECL)
+	output_p = true;
+      else
+	{
+	  cgraph_node_set_iterator csi;
+	  gcc_assert (TREE_CODE (p->decl) == FUNCTION_DECL);
+	  csi = cgraph_node_set_find (set, cgraph_node (p->decl));
+	  output_p = !csi_end_p (csi);
+	}
+
+      if (output_p)
+	{
+	  output_expr_operand (ob, p->decl);
+	  LTO_DEBUG_TOKEN ("alias_target");
+	  output_expr_operand (ob, p->target);
+	}
     }
 
   output_zero (ob);
Index: testsuite/g++.dg/lto/20081219_0.C
===================================================================
--- testsuite/g++.dg/lto/20081219_0.C	(revision 0)
+++ testsuite/g++.dg/lto/20081219_0.C	(revision 0)
@@ -0,0 +1,72 @@
+// { dg-do "link" }
+// { dg-options "{-fPIC -fwhopr -O2}" }
+// { dg-extra-ld-options "-O2 -fPIC -fwhopr -shared" }
+
+typedef long int ptrdiff_t;
+extern "C"
+{
+  typedef struct
+  {
+  }
+  __mbstate_t;
+  namespace std
+  {
+    class exception
+    {
+    };
+  }
+}
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  template < typename _Alloc > class allocator;
+  template < class _CharT > struct char_traits;
+}
+typedef __mbstate_t mbstate_t;
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  using::mbstate_t;
+  typedef ptrdiff_t streamsize;
+  template < typename _CharT, typename _Traits =
+    char_traits < _CharT > >class basic_istream;
+  template < typename _CharT, typename _Traits =
+    char_traits < _CharT >, typename _Alloc =
+    allocator < _CharT > >class basic_stringbuf;
+  class ios_base
+  {
+  public:class failure:public exception
+    {
+    };
+    virtual ~ ios_base ();
+  };
+  template < typename _CharT, typename _Traits > class basic_streambuf
+  {
+  };
+template < typename _CharT, typename _Traits > class basic_ios:public
+    ios_base
+  {
+  };
+template < typename _CharT, typename _Traits > class basic_istream:virtual public basic_ios < _CharT,
+    _Traits
+    >
+  {
+    typedef basic_streambuf < _CharT, _Traits > __streambuf_type;
+  protected:streamsize _M_gcount;
+  public: explicit basic_istream (__streambuf_type * __sb):_M_gcount (streamsize
+	       (0))
+    {
+    }
+  };
+template < typename _CharT, typename _Traits, typename _Alloc > class basic_stringbuf:public basic_streambuf < _CharT,
+    _Traits
+    >
+  {
+  };
+  template < typename V, typename I, typename S = std::mbstate_t > struct character
+  {
+  };
+  typedef character < unsigned short, unsigned int >pod_ushort;
+  typedef basic_stringbuf < pod_ushort > stringbuf_type;
+  typedef basic_istream < pod_ushort > istream_type;
+  stringbuf_type strbuf01;
+  istream_type stream (&strbuf01);
+}
Index: testsuite/g++.dg/lto/20081219_1.C
===================================================================
--- testsuite/g++.dg/lto/20081219_1.C	(revision 0)
+++ testsuite/g++.dg/lto/20081219_1.C	(revision 0)
@@ -0,0 +1,42 @@
+typedef struct
+{
+}
+__mbstate_t;
+typedef __mbstate_t mbstate_t;
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  using::mbstate_t;
+  typedef int *__c_locale;
+  class locale
+  {
+    class facet;
+  };
+  class locale::facet
+  {
+  };
+template < typename _CharT > class numpunct:public locale::facet
+  {
+    void _M_initialize_numpunct (__c_locale __cloc = __null);
+  };
+}
+namespace __gnu_cxx __attribute__ ((__visibility__ ("default")))
+{
+  template < typename V, typename I, typename S = std::mbstate_t > struct character
+  {
+  };
+}
+
+namespace __gnu_test
+{
+  using __gnu_cxx::character;
+  typedef character < unsigned short, unsigned int >pod_ushort;
+}
+namespace std
+{
+  using __gnu_test::pod_ushort;
+    template <> void numpunct <
+    pod_ushort >::_M_initialize_numpunct (__c_locale)
+  {
+    pod_ushort *__truename = new pod_ushort[4 + 1];
+  }
+}


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