> > 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. > --- > gcc/cgraphunit.c | 143 ++++++++++++----------- > gcc/doc/extend.texi | 10 +- > 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, 110 insertions(+), 76 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/ipa/symver1.c >
> @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) So we can still write it as follows: +__attribute__ ((__symver__ ("foo@@VERS_2")))) +__attribute__ ((__symver__ ("foo@@VERS_3")))) +int symver_foo_v1 (void) I think we should support this syntax so the versions can be added separately by macros mixed with other attributs.... Honza > +@{ > +@} > @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; > + } > + }] > +}