This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] Fix splitting of alias pairs
- From: Diego Novillo <dnovillo at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 19 Dec 2008 09:14:23 -0500
- Subject: [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];
+ }
+}