public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-05 19:30 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-05 19:30 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c1f976e7a6f7ac66df1063105926e4b139b6373b

commit c1f976e7a6f7ac66df1063105926e4b139b6373b
Author: Alexandre Oliva <oliva@gnu.org>
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        | 36 ++++++++++++++++++++++
 .../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, 120 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 4f02d765d28..abfbbbf6294 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2699,6 +2699,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;
@@ -2706,13 +2711,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 03ff9c1e425..c1490e627df 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5904,6 +5904,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 6d72ad8ff43..00f19962e5d 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2221,6 +2221,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 7f4414410b0..22b7e3ab7bf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4174,7 +4174,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 <cgraph_node *> (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..2fe1948aed9 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__ ((__alias__ ("FOOVAR_A")));
 int var_a = 1;
 
 void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A")));
 
+void foo_alias () __attribute__ ((__alias__ ("FOOBAR_A")));
+
 void
 foo_a ()
 {
@@ -31,9 +34,42 @@ 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")));
+
+
+ /* The *u* symbols are not defined, so the sym_aliases do not clash.  ??? Is
+    this just an implementation artifact, or a feature someone might actually
+    rely on?  */
+extern int var_u1 __attribute__ ((__sym_alias__ ("VAR_U")));
+extern int var_u2 __attribute__ ((__sym_alias__ ("VAR_U")));
+
+void foo_u1 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+void foo_u2 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+
+
 /* { 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" } } */
+/* { dg-final { scan-assembler-not "VAR_U" } } */
+/* { dg-final { scan-assembler-not "FOOBAR_U" } } */
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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-05 21:51 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-05 21:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7a95e16ea4a516c9cfd04d6c73cd806a1fa7ccc4

commit 7a95e16ea4a516c9cfd04d6c73cd806a1fa7ccc4
Author: Alexandre Oliva <oliva@gnu.org>
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        | 36 ++++++++++++++++++++++
 .../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, 120 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 4f02d765d28..abfbbbf6294 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2699,6 +2699,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;
@@ -2706,13 +2711,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 03ff9c1e425..c1490e627df 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5904,6 +5904,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 6d72ad8ff43..00f19962e5d 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2221,6 +2221,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 7f4414410b0..22b7e3ab7bf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4174,7 +4174,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 <cgraph_node *> (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..2fe1948aed9 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__ ((__alias__ ("FOOVAR_A")));
 int var_a = 1;
 
 void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A")));
 
+void foo_alias () __attribute__ ((__alias__ ("FOOBAR_A")));
+
 void
 foo_a ()
 {
@@ -31,9 +34,42 @@ 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")));
+
+
+ /* The *u* symbols are not defined, so the sym_aliases do not clash.  ??? Is
+    this just an implementation artifact, or a feature someone might actually
+    rely on?  */
+extern int var_u1 __attribute__ ((__sym_alias__ ("VAR_U")));
+extern int var_u2 __attribute__ ((__sym_alias__ ("VAR_U")));
+
+void foo_u1 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+void foo_u2 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+
+
 /* { 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" } } */
+/* { dg-final { scan-assembler-not "VAR_U" } } */
+/* { dg-final { scan-assembler-not "FOOBAR_U" } } */
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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-03  1:46 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-03  1:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:dcab56afdefe7b43bdf9a90a86300a675d5d7193

commit dcab56afdefe7b43bdf9a90a86300a675d5d7193
Author: Alexandre Oliva <oliva@gnu.org>
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        | 36 ++++++++++++++++++++++
 .../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, 120 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 7294ff27277..5f811c937f0 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2696,6 +2696,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;
@@ -2703,13 +2708,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 e5a1ee54cb3..1ed281dfa76 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5904,6 +5904,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 4aca96de04e..77ea5c9e022 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4174,7 +4174,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 <cgraph_node *> (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..2fe1948aed9 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__ ((__alias__ ("FOOVAR_A")));
 int var_a = 1;
 
 void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A")));
 
+void foo_alias () __attribute__ ((__alias__ ("FOOBAR_A")));
+
 void
 foo_a ()
 {
@@ -31,9 +34,42 @@ 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")));
+
+
+ /* The *u* symbols are not defined, so the sym_aliases do not clash.  ??? Is
+    this just an implementation artifact, or a feature someone might actually
+    rely on?  */
+extern int var_u1 __attribute__ ((__sym_alias__ ("VAR_U")));
+extern int var_u2 __attribute__ ((__sym_alias__ ("VAR_U")));
+
+void foo_u1 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+void foo_u2 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+
+
 /* { 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" } } */
+/* { dg-final { scan-assembler-not "VAR_U" } } */
+/* { dg-final { scan-assembler-not "FOOBAR_U" } } */
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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-02 17:48 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-02 17:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:061a135187ac7d6a9e61bf6a1c9d6ea0eded3431

commit 061a135187ac7d6a9e61bf6a1c9d6ea0eded3431
Author: Alexandre Oliva <oliva@gnu.org>
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        | 36 ++++++++++++++++++++++
 .../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, 120 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 45610b595b2..5b86b0c7e37 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2699,6 +2699,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;
@@ -2706,13 +2711,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 83fb1c4cc93..37f518c6068 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5904,6 +5904,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 b32aa7bac11..266e04747b3 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4174,7 +4174,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 <cgraph_node *> (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..2fe1948aed9 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__ ((__alias__ ("FOOVAR_A")));
 int var_a = 1;
 
 void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A")));
 
+void foo_alias () __attribute__ ((__alias__ ("FOOBAR_A")));
+
 void
 foo_a ()
 {
@@ -31,9 +34,42 @@ 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")));
+
+
+ /* The *u* symbols are not defined, so the sym_aliases do not clash.  ??? Is
+    this just an implementation artifact, or a feature someone might actually
+    rely on?  */
+extern int var_u1 __attribute__ ((__sym_alias__ ("VAR_U")));
+extern int var_u2 __attribute__ ((__sym_alias__ ("VAR_U")));
+
+void foo_u1 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+void foo_u2 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+
+
 /* { 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" } } */
+/* { dg-final { scan-assembler-not "VAR_U" } } */
+/* { dg-final { scan-assembler-not "FOOBAR_U" } } */
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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:48 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b4e02915b24903060a8c9914c455d0af02d06cd6

commit b4e02915b24903060a8c9914c455d0af02d06cd6
Author: Alexandre Oliva <oliva@gnu.org>
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        | 36 ++++++++++++++++++++++
 .../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, 120 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 <cgraph_node *> (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..2fe1948aed9 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__ ((__alias__ ("FOOVAR_A")));
 int var_a = 1;
 
 void foo_a () __attribute__ ((__sym_alias__ ("FOOBAR_A")));
 
+void foo_alias () __attribute__ ((__alias__ ("FOOBAR_A")));
+
 void
 foo_a ()
 {
@@ -31,9 +34,42 @@ 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")));
+
+
+ /* The *u* symbols are not defined, so the sym_aliases do not clash.  ??? Is
+    this just an implementation artifact, or a feature someone might actually
+    rely on?  */
+extern int var_u1 __attribute__ ((__sym_alias__ ("VAR_U")));
+extern int var_u2 __attribute__ ((__sym_alias__ ("VAR_U")));
+
+void foo_u1 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+void foo_u2 () __attribute__ ((__sym_alias__ ("FOOBAR_U")));
+
+
 /* { 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" } } */
+/* { dg-final { scan-assembler-not "VAR_U" } } */
+/* { dg-final { scan-assembler-not "FOOBAR_U" } } */
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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:42 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:42 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a7933a8ebf4c13a82c17555794bd3ac46c69b0eb

commit a7933a8ebf4c13a82c17555794bd3ac46c69b0eb
Author: Alexandre Oliva <oliva@gnu.org>
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 <cgraph_node *> (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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:40 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:40 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:19e952dc9604fa0f789d4744d21f4f5b7a1cc590

commit 19e952dc9604fa0f789d4744d21f4f5b7a1cc590
Author: Alexandre Oliva <oliva@gnu.org>
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 <cgraph_node *> (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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:13 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:13 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:de033fdcd6d4b25f00ca3e5c1c26087f9b38c8d2

commit de033fdcd6d4b25f00ca3e5c1c26087f9b38c8d2
Author: Alexandre Oliva <oliva@gnu.org>
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        | 19 ++++++++++++++++
 .../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, 103 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..098c525454a 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) && 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 <cgraph_node *> (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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:11 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:81b38778df03e10777c56a9500bed36296dc2b50

commit 81b38778df03e10777c56a9500bed36296dc2b50
Author: Alexandre Oliva <oliva@gnu.org>
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        | 19 ++++++++++++++++
 .../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, 103 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..098c525454a 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) && 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..27393f273de 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 <cgraph_node *> (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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 23:07 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 23:07 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d75b8320c39665fbe186263eda8682000bebb619

commit d75b8320c39665fbe186263eda8682000bebb619
Author: Alexandre Oliva <oliva@gnu.org>
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        | 19 ++++++++++++++++
 .../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, 103 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..098c525454a 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) && 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..2520148220f 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 <cgraph_node *> (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 (node->decl) = remove_attribute ("sym_alias",
+						   DECL_ATTRIBUTES
+						   (node->decl));
+  DECL_ATTRIBUTES (node->decl) = remove_attribute ("sym alias",
+						   DECL_ATTRIBUTES
+						   (node->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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 22:24 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 22:24 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e7239bc8016a0cdb02492aa23c6e4f29fea5208a

commit e7239bc8016a0cdb02492aa23c6e4f29fea5208a
Author: Alexandre Oliva <oliva@gnu.org>
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                                       | 20 +++++++++++++++++++-
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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, 97 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..098c525454a 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) && 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..e36de9a7868 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 <cgraph_node *> (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);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 22:19 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 22:19 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2f731a5944892185cea0def14f3478e0a3cf5ff0

commit 2f731a5944892185cea0def14f3478e0a3cf5ff0
Author: Alexandre Oliva <oliva@gnu.org>
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/doc/extend.texi                                 |  8 +++++++-
 gcc/symtab.cc                                       | 20 +++++++++++++++++++-
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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 +++++++++++++++++
 8 files changed, 94 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..098c525454a 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) && 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/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..e36de9a7868 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 <cgraph_node *> (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);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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 <typeinfo>
+
+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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 21:51 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 21:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f39376cb3c2c2c9b740da0ddf24410fe5b349ff3

commit f39376cb3c2c2c9b740da0ddf24410fe5b349ff3
Author: Alexandre Oliva <oliva@gnu.org>
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/doc/extend.texi                                 |  2 +-
 gcc/symtab.cc                                       | 20 +++++++++++++++++++-
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 8 files changed, 86 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..1f0a0ada336 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 (decl))
+    node->copy_visibility_from (dnode);
 
   return clone;
 }
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/doc/extend.texi b/gcc/doc/extend.texi
index f16571147d4..eff776a4bc8 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4173,7 +4173,7 @@ 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.
 
 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..e36de9a7868 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 <cgraph_node *> (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);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..83d1936d275 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 21:45 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 21:45 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:bad13a9698a5c0b4c53c5690dc958a565228f8f6

commit bad13a9698a5c0b4c53c5690dc958a565228f8f6
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                      | 15 +++++++++++----
 gcc/c/c-decl.cc                                     |  5 +++++
 gcc/doc/extend.texi                                 |  2 +-
 gcc/symtab.cc                                       | 20 +++++++++++++++++++-
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 8 files changed, 85 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..c52180eccfd 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,15 @@ 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);
+  node->copy_visibility_from (decl);
 
   return clone;
 }
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/doc/extend.texi b/gcc/doc/extend.texi
index f16571147d4..eff776a4bc8 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4173,7 +4173,7 @@ 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.
 
 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..e36de9a7868 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 <cgraph_node *> (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);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..83d1936d275 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 21:41 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 21:41 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cd771ac17fcfccd0cbd564178152ba2a3929d22a

commit cd771ac17fcfccd0cbd564178152ba2a3929d22a
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                      | 15 +++++++++++----
 gcc/c/c-decl.cc                                     |  5 +++++
 gcc/doc/extend.texi                                 |  2 +-
 gcc/symtab.cc                                       | 20 +++++++++++++++++++-
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 8 files changed, 85 insertions(+), 19 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..0a353e7ad58 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,15 @@ 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);
+  node->copy_visibility_from (decl);
 
   return clone;
 }
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/doc/extend.texi b/gcc/doc/extend.texi
index f16571147d4..eff776a4bc8 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4173,7 +4173,7 @@ 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.
 
 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..e36de9a7868 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 <cgraph_node *> (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);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..83d1936d275 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 21:37 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 21:37 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:27f2777fd67327638a100ee1310087841922194f

commit 27f2777fd67327638a100ee1310087841922194f
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                      |  6 ++++++
 gcc/c/c-decl.cc                                     |  5 +++++
 gcc/doc/extend.texi                                 |  2 +-
 gcc/symtab.cc                                       | 17 +++++++++++++++++
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 8 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..6f3069d3adc 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;
@@ -2681,6 +2686,7 @@ create_sym_alias_decl (tree decl, tree id)
   else
     cgraph_node::create_same_body_alias (clone, decl);
     // cgraph_node::create_alias (clone, decl);
+  clone->copy_visibility_from (decl);
 
   return clone;
 }
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/doc/extend.texi b/gcc/doc/extend.texi
index f16571147d4..eff776a4bc8 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4173,7 +4173,7 @@ 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.
 
 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..08bb2eac6aa 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 <cgraph_node *> (node);
       if (cnode && cnode->clones && with_clones)
@@ -1978,6 +1994,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 (replacement);
     }
 }
 
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..83d1936d275 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 21:07 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 21:07 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a4993d01556a7fe36e21ab0a2198f74ce7a9979b

commit a4993d01556a7fe36e21ab0a2198f74ce7a9979b
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                      |  5 +++++
 gcc/c/c-decl.cc                                     |  5 +++++
 gcc/symtab.cc                                       | 16 ++++++++++++++++
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 7 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..eb9dead2549 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;
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/symtab.cc b/gcc/symtab.cc
index 43ba88d7939..64cde21cad8 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 <cgraph_node *> (node);
       if (cnode && cnode->clones && with_clones)
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..83d1936d275 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 20:52 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 20:52 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7ad8b5e5539c788cfa019f610b3a149887bd58b3

commit 7ad8b5e5539c788cfa019f610b3a149887bd58b3
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                      |  5 +++++
 gcc/c/c-decl.cc                                     |  5 +++++
 gcc/symtab.cc                                       | 16 ++++++++++++++++
 .../c-c++-common/torture/attr-sym-alias-1.c         | 19 +++++++++++++++++++
 .../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     | 15 +++++++++++++++
 7 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..eb9dead2549 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;
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/symtab.cc b/gcc/symtab.cc
index 43ba88d7939..64cde21cad8 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 <cgraph_node *> (node);
       if (cnode && cnode->clones && with_clones)
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..5abab88f6a0 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  extern std::typeinfo __attribute__ ((__alias__ ("FOOCLS_D"))) foo_d_typeinfo;
+}
+
+extern std::typeinfo __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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 20:47 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 20:47 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c7d354c705966928b3dbdcd6a9ee5f1502b594d1

commit c7d354c705966928b3dbdcd6a9ee5f1502b594d1
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                        |  5 +++++
 gcc/c/c-decl.cc                                       |  5 +++++
 gcc/symtab.cc                                         | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c | 17 +++++++++++++----
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c |  7 -------
 gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C       | 15 +++++++++++++++
 7 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..eb9dead2549 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;
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/symtab.cc b/gcc/symtab.cc
index 43ba88d7939..c5fa8ff873c 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 (tree attr = 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 <cgraph_node *> (node);
       if (cnode && cnode->clones && with_clones)
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..913f2645448 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" } */
 
 
@@ -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 ()
+{
+}
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..5abab88f6a0 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  extern std::typeinfo __attribute__ ((__alias__ ("FOOCLS_D"))) foo_d_typeinfo;
+}
+
+extern std::typeinfo __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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes
@ 2023-12-01 20:43 Alexandre Oliva
  0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Oliva @ 2023-12-01 20:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:46303b8418140f8f76f239350903289c718416f8

commit 46303b8418140f8f76f239350903289c718416f8
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Fri Dec 1 15:48:44 2023 -0300

    incremental sym_alias changes

Diff:
---
 gcc/attribs.cc                                        |  5 +++++
 gcc/c/c-decl.cc                                       |  5 +++++
 gcc/symtab.cc                                         | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-1.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-2.c | 17 +++++++++++++----
 gcc/testsuite/c-c++-common/torture/attr-sym-alias-3.c |  7 -------
 gcc/testsuite/g++.dg/torture/attr-sym-alias-1.C       | 15 +++++++++++++++
 7 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c75ca6974cb..eb9dead2549 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;
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c5a7e56f4ec..098c525454a 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) && 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/symtab.cc b/gcc/symtab.cc
index 43ba88d7939..939d5667928 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 (tree attr = 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_identifer ("sym_alias"));
+	  }
+
       /* Update also possible inline clones sharing a decl.  */
       cnode = dyn_cast <cgraph_node *> (node);
       if (cnode && cnode->clones && with_clones)
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..b0167786914 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
@@ -31,9 +31,28 @@ 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 "FOOVAR_A" } } */
 /* { 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..913f2645448 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" } */
 
 
@@ -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 ()
+{
+}
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..5abab88f6a0 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,18 @@ namespace c {
   }
 }
 
+#include <typeinfo>
+
+namespace d {
+  namespace {
+    class __attribute__ ((__sym_alias__ ("FOOCLS_D"))) foo {};
+  }
+
+  extern std::typeinfo __attribute__ ((__alias__ ("FOOCLS_D"))) foo_d_typeinfo;
+}
+
+extern std::typeinfo __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 +82,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" } } */

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2023-12-05 21:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-05 19:30 [gcc(refs/users/aoliva/heads/testme)] incremental sym_alias changes Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2023-12-05 21:51 Alexandre Oliva
2023-12-03  1:46 Alexandre Oliva
2023-12-02 17:48 Alexandre Oliva
2023-12-01 23:48 Alexandre Oliva
2023-12-01 23:42 Alexandre Oliva
2023-12-01 23:40 Alexandre Oliva
2023-12-01 23:13 Alexandre Oliva
2023-12-01 23:11 Alexandre Oliva
2023-12-01 23:07 Alexandre Oliva
2023-12-01 22:24 Alexandre Oliva
2023-12-01 22:19 Alexandre Oliva
2023-12-01 21:51 Alexandre Oliva
2023-12-01 21:45 Alexandre Oliva
2023-12-01 21:41 Alexandre Oliva
2023-12-01 21:37 Alexandre Oliva
2023-12-01 21:07 Alexandre Oliva
2023-12-01 20:52 Alexandre Oliva
2023-12-01 20:47 Alexandre Oliva
2023-12-01 20:43 Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).