From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2140) id 795B2385C416; Fri, 1 Dec 2023 23:42:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 795B2385C416 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1701474171; bh=ZWLfc/05+vcPtQENFT3iunXs1iBoh4JnDo6XLVGewWU=; h=From:To:Subject:Date:From; b=CbJHZLB8wfMjW8lEWEKhWREWagdxT1F7GcDxZu73LP1ZFEuYPajHFFL7rqZ0YgwRw RmtrimjCcbLelVO3BA6WcLgt2Mv5NpsG5mLKSySvqs6GEfCfP/7+9bJl+prseeB1+H HdBTYKqQ6G4jicJ4bd2t2r1QeqoWrUP5FigNWCGk= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alexandre Oliva To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes X-Act-Checkin: gcc X-Git-Author: Alexandre Oliva X-Git-Refname: refs/users/aoliva/heads/testme X-Git-Oldrev: f12dd02228acd65623bf2646f4eb115cf61121f6 X-Git-Newrev: a7933a8ebf4c13a82c17555794bd3ac46c69b0eb Message-Id: <20231201234251.795B2385C416@sourceware.org> Date: Fri, 1 Dec 2023 23:42:51 +0000 (GMT) List-Id: https://gcc.gnu.org/g:a7933a8ebf4c13a82c17555794bd3ac46c69b0eb commit a7933a8ebf4c13a82c17555794bd3ac46c69b0eb Author: Alexandre Oliva Date: Fri Dec 1 15:48:44 2023 -0300 incremental sym_alias changes Diff: --- gcc/attribs.cc | 16 +++++++++---- gcc/c/c-decl.cc | 5 +++++ gcc/cp/decl2.cc | 3 +++ gcc/doc/extend.texi | 8 ++++++- gcc/symtab.cc | 26 +++++++++++++++++++++- .../c-c++-common/torture/attr-sym-alias-1.c | 24 ++++++++++++++++++++ .../c-c++-common/torture/attr-sym-alias-2.c | 21 ++++++++++++----- .../c-c++-common/torture/attr-sym-alias-3.c | 7 ------ gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C | 17 ++++++++++++++ 9 files changed, 108 insertions(+), 19 deletions(-) diff --git a/gcc/attribs.cc b/gcc/attribs.cc index c75ca6974cb..f91c56316f3 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -2667,6 +2667,11 @@ create_sym_alias_decl (tree decl, tree id) tree clone = copy_node (decl); DECL_ATTRIBUTES (clone) = remove_attribute (attr_str, DECL_ATTRIBUTES (decl)); + /* Mark it as a "sym alias" for decl, an internal attribute that + enables symbol_table::insert_to_assembler_name_hash can recognize + sym_alias decls. */ + DECL_ATTRIBUTES (clone) = tree_cons (get_identifier ("sym alias"), + decl, DECL_ATTRIBUTES (clone)); SET_DECL_ASSEMBLER_NAME (clone, id); TREE_USED (id) = 1; TREE_USED (clone) = 1; @@ -2674,13 +2679,16 @@ create_sym_alias_decl (tree decl, tree id) DECL_EXTERNAL (clone) = 0; TREE_STATIC (clone) = 1; + symtab_node *node; if (VAR_P (clone)) // DECL_READ_P (clone) = 1; - // varpool_node::create_extra_name_alias (clone, decl); - varpool_node::create_alias (clone, decl); + // node = varpool_node::create_extra_name_alias (clone, decl); + node = varpool_node::create_alias (clone, decl); else - cgraph_node::create_same_body_alias (clone, decl); - // cgraph_node::create_alias (clone, decl); + node = cgraph_node::create_same_body_alias (clone, decl); + // node = cgraph_node::create_alias (clone, decl); + if (symtab_node *dnode = symtab_node::get_create (decl)) + node->copy_visibility_from (dnode); return clone; } diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index c5a7e56f4ec..9e894393daf 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5902,6 +5902,11 @@ finish_decl (tree decl, location_t init_loc, tree init, set_user_assembler_name (decl, asmspec); } + /* Give attribute sym_alias a chance to make the symbol name + available for aliasing, even for a static local variable. */ + if (VAR_P (decl) && !DECL_EXTERNAL (decl) && is_global_var (decl)) + varpool_node::get_create (decl); + if (DECL_FILE_SCOPE_P (decl)) { if (DECL_INITIAL (decl) == NULL_TREE diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index c7f009beaf0..9b4afb3d889 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2219,6 +2219,9 @@ copy_interface (tree dest, tree decl) DECL_INTERFACE_KNOWN (dest) = DECL_INTERFACE_KNOWN (decl); DECL_VISIBILITY (dest) = DECL_VISIBILITY (decl); DECL_VISIBILITY_SPECIFIED (dest) = DECL_VISIBILITY_SPECIFIED (decl); + if (symtab_node *dest_node = symtab_node::get (dest)) + if (symtab_node *decl_node = symtab_node::get (decl)) + decl_node->copy_visibility_from (dest_node); } /* Propagate linkage changes to sym aliases. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f16571147d4..408a1d6f56a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4173,7 +4173,13 @@ declarations. Aliases introduced with this attribute, such as @samp{f_u64} in the example above, are assembly symbol names: they do not undergo C++ name mangling, and are not made visible in any scope in the source language. -They can, however, can be named as alias targets. +They can, however, be named as alias targets, as long as their +definition is output. Naming a @samp{sym_alias} as an alias target will +@emph{not} cause a definition to be output if it otherwise wouldn't. +This may affect inline functions, C++ template instantiations, and other +synthesized definitions that would have to be (synthesized and) compiled +in order for the @samp{sym_alias} to be considered as a potential alias +target. This attribute requires assembler and object file support for aliases, and may not be available on all targets. diff --git a/gcc/symtab.cc b/gcc/symtab.cc index 43ba88d7939..44df52095c1 100644 --- a/gcc/symtab.cc +++ b/gcc/symtab.cc @@ -187,6 +187,22 @@ symbol_table::insert_to_assembler_name_hash (symtab_node *node, (*aslot)->previous_sharing_asm_name = node; *aslot = node; + /* Check for sym_alias name clashes. In create_sym_alias_decl, + we check for a preexisting definition using the same + assembler_name, so here we check for a previously-defined + sym_name, marked with a "sym name" pseudo-attribute that + points back at the declaration for which it was created. */ + if (symtab_node *sym_node = node->next_sharing_asm_name) + if (lookup_attribute ("sym alias", + DECL_ATTRIBUTES (sym_node->decl))) + { + error_at (DECL_SOURCE_LOCATION (node->decl), + "duplicate symbol name %qE", decl); + inform (DECL_SOURCE_LOCATION (sym_node->decl), + "already used by %qD in a %qE attribute", + sym_node->decl, get_identifier ("sym_alias")); + } + /* Update also possible inline clones sharing a decl. */ cnode = dyn_cast (node); if (cnode && cnode->clones && with_clones) @@ -1949,8 +1965,9 @@ symtab_node::noninterposable_alias (symtab_node *node, void *data) void symtab_node::remap_sym_alias_target (tree replaced, tree replacement) { + symtab_node *repl_node = NULL; if (!decl_in_symtab_p (replacement) - || !symtab_node::get (replacement)) + || !(repl_node = symtab_node::get (replacement))) return; FOR_EACH_SYM_ALIAS (sym, DECL_ATTRIBUTES (replaced)) @@ -1978,6 +1995,7 @@ symtab_node::remap_sym_alias_target (tree replaced, tree replacement) else cgraph_node::create_same_body_alias (sym_node->decl, replacement); // cgraph_node::create_alias (sym_node->decl, replacement); + sym_node->copy_visibility_from (repl_node); } } @@ -2008,6 +2026,12 @@ symtab_node::noninterposable_alias (void) /* Otherwise create a new one. */ new_decl = copy_node (node->decl); + DECL_ATTRIBUTES (new_decl) = remove_attribute ("sym_alias", + DECL_ATTRIBUTES + (new_decl)); + DECL_ATTRIBUTES (new_decl) = remove_attribute ("sym alias", + DECL_ATTRIBUTES + (new_decl)); DECL_DLLIMPORT_P (new_decl) = 0; tree name = clone_function_name (node->decl, "localalias"); if (!flag_wpa) diff --git a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c index 61af50cb552..55dc7db6299 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c +++ b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c @@ -2,10 +2,13 @@ /* { dg-require-alias "" } */ extern int var_a __attribute__ ((__sym_alias__ ("FOOVAR_A"))); +extern int var_alias __attribute__ ((__sym_alias__ ("FOOVAR_A"))); int var_a = 1; void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A"))); +void foo_alias () __attribute__ ((__sym_alias__ ("FOOBAR_A"))); + void foo_a () { @@ -31,9 +34,30 @@ foo_c () } +void baf () {} + +void foo_x () { + extern void baf () __attribute__ ((__sym_alias__ ("FOO_BAF"))); + extern void bad () /* ok, but not defined, so no alias issued. */ + __attribute__ ((__sym_alias__ ("FOO_BAD"))); + extern void bar () __attribute__ ((__sym_alias__ ("FOO_BAR"))); + + static int x __attribute__ ((sym_alias ("FOO_x"))); +} + +void bar () {} + +extern int xr __attribute__ ((alias ("FOO_x"))); + + /* { dg-final { scan-assembler "FOOBAR_A" } } */ +/* { dg-final { scan-assembler "foo_alias" } } */ /* { dg-final { scan-assembler "FOOVAR_A" } } */ +/* { dg-final { scan-assembler "var_alias" } } */ /* { dg-final { scan-assembler "FOOBAR_B" } } */ /* { dg-final { scan-assembler "FOOVAR_B" } } */ /* { dg-final { scan-assembler "FOOBAR_C" } } */ /* { dg-final { scan-assembler "FOOVAR_C" } } */ +/* { dg-final { scan-assembler "FOO_BAF" } } */ +/* { dg-final { scan-assembler "FOO_BAR" } } */ +/* { dg-final { scan-assembler-not "FOO_BAD" } } */ diff --git a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c index 67dcd4fd7e1..f692a552606 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c +++ b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c @@ -7,16 +7,14 @@ struct s }; void foo () { - extern void bar () __attribute__ ((__sym_alias__ ("FOO_BAR"))); /* ok */ + extern void bar () __attribute__ ((__sym_alias__ ("FOO_BAR"))); /* Ok. */ int i __attribute__ ((sym_alias ("FOO_i"))); /* { dg-warning "ignored" } */ - /* ??? X cannot be an alias target; should this be flagged? ... */ static int x __attribute__ ((sym_alias ("FOO_x"))); static int sx __attribute__ ((alias ("FOO_x"))); /* { dg-warning "ignored" } */ extern int xx __attribute__ ((alias ("FOO_x"))); /* { dg-warning "ignored" } */ + extern int y __attribute__ ((sym_alias ("FOO_y"))); /* Ok. */ } -/* ??? ... or should XR be accepted? */ -extern int xr __attribute__ ((alias ("FOO_x"))); /* { dg-error "undefined" "" { xfail c++ } } */ int dr __attribute__ ((alias ("FOO_x"))); /* { dg-error "defined both" } */ @@ -40,7 +38,7 @@ int l __attribute__ ((sym_alias ("L_fn"))); extern "C" #endif void -L_fn () /* { dg-error "duplicate" "" { xfail *-*-* } } */ +L_fn () /* { dg-error "duplicate" "" } */ { } @@ -53,7 +51,7 @@ m () { } -int M_var; /* { dg-error "duplicate" "" { xfail *-*-* } } */ +int M_var; /* { dg-error "duplicate" "" } */ void __attribute__ ((sym_alias ("N_sym"))) @@ -88,3 +86,14 @@ void __attribute__ ((sym_alias ("Q_sym"))) q_fn2 () /* { dg-error "duplicate" } */ { } + +int __attribute__ ((sym_alias ("R_var"))) +R_var; /* { dg-error "duplicate" } */ + +#ifdef __cplusplus +extern "C" +#endif +void __attribute__ ((sym_alias ("S_fn"))) +S_fn () /* { dg-error "duplicate" } */ +{ +} diff --git a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c index 0052485a30a..52f8fb76496 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c +++ b/gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c @@ -10,13 +10,6 @@ foo_a () void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A"))); } -#if 0 // __cplusplus -/* Without this declaration before the local declaration below, the - attributes of the local declaration do not get propagated to the - (global) namespace scope. */ -extern int var_b; -#endif - void foo_b () { diff --git a/gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C b/gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C index 579eda1a473..51729994913 100644 --- a/gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C +++ b/gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C @@ -45,6 +45,20 @@ namespace c { } } +#include + +namespace d { + namespace { + class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo { + virtual ~foo() {} // typeid(foo) is not defined otherwise. + }; + } + + extern std::type_info __attribute__ ((__alias__ ("FOOCLS_D"))) foo_d_typeinfo; +} + +extern std::type_info __attribute__ ((__alias__ ("FOOCLS_C"))) foo_c_typeinfo; + /* { dg-final { scan-assembler "FOOCLS_A" } } */ /* { dg-final { scan-assembler "FOOCLS_A_Dupe" } } */ /* { dg-final { scan-assembler "FOOBAR_A" } } */ @@ -70,3 +84,6 @@ namespace c { /* { dg-final { scan-assembler "FOODTR_C_Base" } } */ /* { dg-final { scan-assembler "FOODTR_C_Del" } } */ /* { dg-final { scan-assembler "FOOVAR_C" } } */ +/* { dg-final { scan-assembler "FOOCLS_D" } } */ +/* { dg-final { scan-assembler "foo_d_typeinfo" } } */ +/* { dg-final { scan-assembler "foo_c_typeinfo" } } */