From cdcba1ea35704e2e6e9197eb8ed2f211ddccb0f3 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva <aoliva@redhat.com> Date: Thu, 20 Oct 2005 19:30:23 +0000 Subject: [PATCH] re PR middle-end/24295 (Xorg broken, #pragma weak foo = bar no longer causes bar to be referenced) gcc/ChangeLog: PR middle-end/24295 * cgraphunit.c (cgraph_varpool_remove_unreferenced_decls): Mark alias targets. * varasm.c (find_decl_and_mark_needed): After cgraph global info is ready, stop marking functions, but still mark variables. gcc/testsuite/ChangeLog: PR middle-end/24295 * g++.old-deja/g++.abi/vtable2.C: Do not introduce external declarations with the same names as thunks' alias targets, use aliases instead. * gcc.dg/attr-alias-3.c: New test. * gcc.dg/weak/weak-14.c, gcc.dg/weak/weak-14a.c: New test. From-SVN: r105688 --- gcc/ChangeLog | 8 +++ gcc/cgraphunit.c | 2 + gcc/testsuite/ChangeLog | 9 ++++ gcc/testsuite/g++.old-deja/g++.abi/vtable2.C | 8 +-- gcc/testsuite/gcc.dg/attr-alias-3.c | 55 ++++++++++++++++++++ gcc/testsuite/gcc.dg/weak/weak-14.c | 33 ++++++++++++ gcc/varasm.c | 33 ++++++------ 7 files changed, 128 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/attr-alias-3.c create mode 100644 gcc/testsuite/gcc.dg/weak/weak-14.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3a9a8fa564a..0a6e2a09288a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-10-20 Alexandre Oliva <aoliva@redhat.com> + + PR middle-end/24295 + * cgraphunit.c (cgraph_varpool_remove_unreferenced_decls): Mark + alias targets. + * varasm.c (find_decl_and_mark_needed): After cgraph global info + is ready, stop marking functions, but still mark variables. + 2005-10-20 Richard Guenther <rguenther@suse.de> PR c++/24439 diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 181ee4e6329a..244367d2899f 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -322,6 +322,8 @@ cgraph_varpool_remove_unreferenced_decls (void) node = next; } + /* Make sure we mark alias targets as used targets. */ + finish_aliases_1 (); cgraph_varpool_analyze_pending_decls (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a63875dc995..81cf34170501 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2005-10-20 Alexandre Oliva <aoliva@redhat.com> + + PR middle-end/24295 + * g++.old-deja/g++.abi/vtable2.C: Do not introduce external + declarations with the same names as thunks' alias targets, use + aliases instead. + * gcc.dg/attr-alias-3.c: New test. + * gcc.dg/weak/weak-14.c, gcc.dg/weak/weak-14a.c: New test. + 2005-10-20 Mark Mitchell <mark@codesourcery.com> PR c++/22618 diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C index 275b00343714..bea06e310ea6 100644 --- a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C +++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C @@ -124,8 +124,8 @@ void S4::s1 () // These are tricks to allow us to get raw function pointers for // member functions. extern "C" { -void _ZN2S32s3Ev (); -void _ZN2S42s1Ev (); + void S3_s3 () __attribute__((__alias__ ("_ZN2S32s3Ev"))); + void S4_s1 () __attribute__((__alias__ ("_ZN2S42s1Ev"))); } // IA-64 uses function descriptors not function pointers in its vtables. @@ -169,10 +169,10 @@ int main () INC_VDATA (vtbl, 1); // Skip the RTTI entry. INC_VDATA (vtbl, 1); - if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev)) + if (! CMP_VPTR (vtbl, &S3_s3)) return 5; INC_VPTR (vtbl); - if (! CMP_VPTR (vtbl, &_ZN2S42s1Ev)) + if (! CMP_VPTR (vtbl, &S4_s1)) return 6; INC_VPTR (vtbl); // The S1 vbase offset. diff --git a/gcc/testsuite/gcc.dg/attr-alias-3.c b/gcc/testsuite/gcc.dg/attr-alias-3.c new file mode 100644 index 000000000000..acd1969a3ff8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-alias-3.c @@ -0,0 +1,55 @@ +// { dg-do link } +// { dg-require-alias "" } +// { dg-options "-O2 -fno-common" } + +// Copyright 2005 Free Software Foundation, Inc. +// Contributed by Alexandre Oliva <aoliva@redhat.com> + +// PR middle-end/24295 + +// The unit-at-a-time call graph code used to fail to emit variables +// without external linkage that were only used indirectly, through +// aliases. Although the PR above is about #pragma weak-introduced +// aliases, the underlying machinery is the same. + +#ifndef ATTRIBUTE_USED +# define ATTRIBUTE_USED __attribute__((used)) +#endif + +static int lv1; +extern int Av1a __attribute__((alias ("lv1"))); +int *pv1a = &Av1a; + +static int lv2; +extern int Av2a __attribute__((alias ("lv2"))); +int *pv2a = &lv2; + +static int lv3; +extern int Av3a __attribute__((alias ("lv3"))); +static int *pv3a ATTRIBUTE_USED = &Av3a; + +static int lv4; +extern int Av4a __attribute__((alias ("lv4"))); +static int *pv4a = &Av4a; + +typedef void ftype(void); + +static void lf1(void) {} +extern ftype Af1a __attribute__((alias ("lf1"))); +ftype *pf1a = &Af1a; + +static void lf2(void) {} +extern ftype Af2a __attribute__((alias ("lf2"))); +ftype *pf2a = &Af2a; + +static void lf3(void) {} +extern ftype Af3a __attribute__((alias ("lf3"))); +static ftype *pf3a ATTRIBUTE_USED = &Af3a; + +static void lf4(void) {} +extern ftype Af4a __attribute__((alias ("lf4"))); +static ftype *pf4a = &Af4a; + +main() { + asm volatile ("" : : "m" (pv4a), "m" (pf4a)); +} diff --git a/gcc/testsuite/gcc.dg/weak/weak-14.c b/gcc/testsuite/gcc.dg/weak/weak-14.c new file mode 100644 index 000000000000..fa15624b66fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/weak/weak-14.c @@ -0,0 +1,33 @@ +// { dg-do run } +// { dg-require-weak "" } +// { dg-options "-O2 -fno-common" } + +// Copyright 2005 Free Software Foundation, Inc. +// Contributed by Alexandre Oliva <aoliva@redhat.com> + +// PR middle-end/24295 + +// The unit-at-a-time call graph code used to fail to emit variables +// without external linkage that were only used indirectly, through +// aliases. We might then get linker failures because the static +// variable was not defined, or run-time errors because the weak alias +// ended up pointing somewhere random. + +#include <stdlib.h> + +static unsigned long lv1 = 0xdeadbeefUL; +#pragma weak Av1a = lv1 +extern unsigned long Av1a; + +static unsigned long lf1(void) { return 0x510bea7UL; } +#pragma weak Af1a = lf1 +extern unsigned long Af1a(void); + +int main (void) { + if (! &Av1a + || ! &Af1a + || Av1a != 0xdeadbeefUL + || Af1a() != 0x510bea7UL) + abort (); + exit (0); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 1aee9839e2d3..2aa5e6904daf 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4560,27 +4560,28 @@ find_decl_and_mark_needed (tree decl, tree target) struct cgraph_node *fnode = NULL; struct cgraph_varpool_node *vnode = NULL; - /* C++ thunk emitting code produces aliases late in the game. - Avoid confusing cgraph code in that case. */ - if (!cgraph_global_info_ready) + if (TREE_CODE (decl) == FUNCTION_DECL) { - if (TREE_CODE (decl) == FUNCTION_DECL) - { - fnode = cgraph_node_for_asm (target); - if (fnode == NULL) - vnode = cgraph_varpool_node_for_asm (target); - } - else - { - vnode = cgraph_varpool_node_for_asm (target); - if (vnode == NULL) - fnode = cgraph_node_for_asm (target); - } + fnode = cgraph_node_for_asm (target); + if (fnode == NULL) + vnode = cgraph_varpool_node_for_asm (target); + } + else + { + vnode = cgraph_varpool_node_for_asm (target); + if (vnode == NULL) + fnode = cgraph_node_for_asm (target); } if (fnode) { - cgraph_mark_needed_node (fnode); + /* We can't mark function nodes as used after cgraph global info + is finished. This wouldn't generally be necessary, but C++ + virtual table thunks are introduced late in the game and + might seem like they need marking, although in fact they + don't. */ + if (! cgraph_global_info_ready) + cgraph_mark_needed_node (fnode); return fnode->decl; } else if (vnode) -- GitLab