public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-modules] IPA symver: allow multiple symvers for a definition
@ 2020-08-28 16:04 Nathan Sidwell
0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-08-28 16:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:363080bb8bd2cca81dd9e2e774910a8c8226f430
commit 363080bb8bd2cca81dd9e2e774910a8c8226f430
Author: Martin Liska <mliska@suse.cz>
Date: Mon Aug 24 13:21:10 2020 +0200
IPA symver: allow multiple symvers for a definition
gcc/ChangeLog:
* cgraphunit.c (process_symver_attribute): Allow multiple
symver attributes for one symbol.
* doc/extend.texi: Document the change.
gcc/testsuite/ChangeLog:
* lib/target-supports-dg.exp: Add dg-require-symver.
* lib/target-supports.exp: Likewise.
* gcc.dg/ipa/symver1.c: New test.
Diff:
---
gcc/cgraphunit.c | 143 ++++++++++++++++---------------
gcc/doc/extend.texi | 16 ++--
gcc/testsuite/gcc.dg/ipa/symver1.c | 11 +++
gcc/testsuite/lib/target-supports-dg.exp | 10 +++
gcc/testsuite/lib/target-supports.exp | 12 +++
5 files changed, 116 insertions(+), 76 deletions(-)
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0b1009d0dea..fa3aec79a48 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -720,80 +720,81 @@ process_symver_attribute (symtab_node *n)
{
tree value = lookup_attribute ("symver", DECL_ATTRIBUTES (n->decl));
- if (!value)
- return;
- if (lookup_attribute ("symver", TREE_CHAIN (value)))
+ for (; value != NULL; value = TREE_CHAIN (value))
{
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "multiple versions for one symbol");
- return;
- }
- tree symver = get_identifier_with_length
- (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value))),
- TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value))));
- symtab_node *def = symtab_node::get_for_asmname (symver);
+ /* Starting from bintuils 2.35 gas supports:
+ # Assign foo to bar@V1 and baz@V2.
+ .symver foo, bar@V1
+ .symver foo, baz@V2
+ */
+
+ tree symver = get_identifier_with_length
+ (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value))),
+ TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value))));
+ symtab_node *def = symtab_node::get_for_asmname (symver);
+
+ if (def)
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "duplicate definition of a symbol version");
+ inform (DECL_SOURCE_LOCATION (def->decl),
+ "same version was previously defined here");
+ return;
+ }
+ if (!n->definition)
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "symbol needs to be defined to have a version");
+ return;
+ }
+ if (DECL_COMMON (n->decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "common symbol cannot be versioned");
+ return;
+ }
+ if (DECL_COMDAT (n->decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "comdat symbol cannot be versioned");
+ return;
+ }
+ if (n->weakref)
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "%<weakref%> cannot be versioned");
+ return;
+ }
+ if (!TREE_PUBLIC (n->decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "versioned symbol must be public");
+ return;
+ }
+ if (DECL_VISIBILITY (n->decl) != VISIBILITY_DEFAULT)
+ {
+ error_at (DECL_SOURCE_LOCATION (n->decl),
+ "versioned symbol must have default visibility");
+ return;
+ }
- if (def)
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "duplicate definition of a symbol version");
- inform (DECL_SOURCE_LOCATION (def->decl),
- "same version was previously defined here");
- return;
- }
- if (!n->definition)
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "symbol needs to be defined to have a version");
- return;
- }
- if (DECL_COMMON (n->decl))
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "common symbol cannot be versioned");
- return;
- }
- if (DECL_COMDAT (n->decl))
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "comdat symbol cannot be versioned");
- return;
- }
- if (n->weakref)
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "%<weakref%> cannot be versioned");
- return;
+ /* Create new symbol table entry representing the version. */
+ tree new_decl = copy_node (n->decl);
+
+ DECL_INITIAL (new_decl) = NULL_TREE;
+ if (TREE_CODE (new_decl) == FUNCTION_DECL)
+ DECL_STRUCT_FUNCTION (new_decl) = NULL;
+ SET_DECL_ASSEMBLER_NAME (new_decl, symver);
+ TREE_PUBLIC (new_decl) = 1;
+ DECL_ATTRIBUTES (new_decl) = NULL;
+
+ symtab_node *symver_node = symtab_node::get_create (new_decl);
+ symver_node->alias = true;
+ symver_node->definition = true;
+ symver_node->symver = true;
+ symver_node->create_reference (n, IPA_REF_ALIAS, NULL);
+ symver_node->analyzed = true;
}
- if (!TREE_PUBLIC (n->decl))
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "versioned symbol must be public");
- return;
- }
- if (DECL_VISIBILITY (n->decl) != VISIBILITY_DEFAULT)
- {
- error_at (DECL_SOURCE_LOCATION (n->decl),
- "versioned symbol must have default visibility");
- return;
- }
-
- /* Create new symbol table entry representing the version. */
- tree new_decl = copy_node (n->decl);
-
- DECL_INITIAL (new_decl) = NULL_TREE;
- if (TREE_CODE (new_decl) == FUNCTION_DECL)
- DECL_STRUCT_FUNCTION (new_decl) = NULL;
- SET_DECL_ASSEMBLER_NAME (new_decl, symver);
- TREE_PUBLIC (new_decl) = 1;
- DECL_ATTRIBUTES (new_decl) = NULL;
-
- symtab_node *symver_node = symtab_node::get_create (new_decl);
- symver_node->alias = true;
- symver_node->definition = true;
- symver_node->symver = true;
- symver_node->create_reference (n, IPA_REF_ALIAS, NULL);
- symver_node->analyzed = true;
}
/* Process attributes common for vars and functions. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2bb9b2f72f5..3b37aba5795 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3742,13 +3742,19 @@ foo_v1 (void)
Will produce a @code{.symver foo_v1, foo@@VERS_1} directive in the assembler
output.
-It's an error to define multiple version of a given symbol. In such case
-an alias can be used.
+One can also define multiple version for a given symbol.
@smallexample
-__attribute__ ((__symver__ ("foo@@VERS_2")))
-__attribute__ ((alias ("foo_v1")))
-int symver_foo_v1 (void);
+__attribute__ ((__symver__ ("foo@@VERS_2"), ("foo@@VERS_3")))
+int symver_foo_v1 (void)
+@{
+@}
+
+__attribute__ ((__symver__ ("bar@@VERS_2"))))
+__attribute__ ((__symver__ ("bar@@VERS_3"))))
+int symver_bar_v1 (void)
+@{
+@}
@end smallexample
This example creates an alias of @code{foo_v1} with symbol name
diff --git a/gcc/testsuite/gcc.dg/ipa/symver1.c b/gcc/testsuite/gcc.dg/ipa/symver1.c
new file mode 100644
index 00000000000..645de7ea259
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/symver1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+__attribute__ ((__symver__ ("foo@VER_2")))
+__attribute__ ((__symver__ ("foo@VER_3")))
+int foo()
+{
+ return 2;
+}
+
+/* { dg-final { scan-assembler ".symver.*foo, foo@VER_2" } } */
+/* { dg-final { scan-assembler ".symver.*foo, foo@VER_3" } } */
diff --git a/gcc/testsuite/lib/target-supports-dg.exp b/gcc/testsuite/lib/target-supports-dg.exp
index 5bb99f4e8f9..4a03eaae9ce 100644
--- a/gcc/testsuite/lib/target-supports-dg.exp
+++ b/gcc/testsuite/lib/target-supports-dg.exp
@@ -665,3 +665,13 @@ if { [info procs saved-dg-process-target] == [list] } {
return [dg-process-target-1 $selector]
}
}
+
+# If this target does not support the "symver" attribute, skip this
+# test.
+
+proc dg-require-symver { args } {
+ if { ![ check_symver_available ] } {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ }
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index c24330a27ab..f3fc5b80aea 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10445,3 +10445,15 @@ proc check_effective_target_large_initializer { } {
return 1
}
+# Returns 1 if the target toolchain supports extended
+# syntax of .symver directive, 0 otherwise.
+
+proc check_symver_available { } {
+ return [check_no_compiler_messages symver_available object {
+ int foo(void) { return 0; }
+ int main (void) {
+ asm volatile (".symver foo,foo@VER_1, local");
+ return 0;
+ }
+ }]
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-28 16:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-28 16:04 [gcc/devel/c++-modules] IPA symver: allow multiple symvers for a definition Nathan Sidwell
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).