https://gcc.gnu.org/g:f54b7da000f2d3fe1211957fb2e33a87882461cc
commit f54b7da000f2d3fe1211957fb2e33a87882461cc Author: Alfie Richards <alfie.richa...@arm.com> Date: Thu Feb 13 15:59:43 2025 +0000 Add error cases and tests for Aarch64 FMV. This changes the ambiguation error for C++ to cover cases of differently annotated FMV function sets whose signatures only differ by their return type. It also adds tests covering many FMV errors for Aarch64, including redeclaration, and mixing target_clones and target_versions. gcc/cp/ChangeLog: PR c++/119498 * decl.cc (duplicate_decls): Change logic to not always exclude FMV annotated functions in cases of return type non-ambiguation. gcc/testsuite/ChangeLog: * g++.target/aarch64/mv-and-mvc-error1.C: New test. * g++.target/aarch64/mv-and-mvc-error2.C: New test. * g++.target/aarch64/mv-and-mvc-error3.C: New test. * g++.target/aarch64/mv-error1.C: New test. * g++.target/aarch64/mv-error2.C: New test. * g++.target/aarch64/mv-error3.C: New test. * g++.target/aarch64/mv-error4.C: New test. * g++.target/aarch64/mv-error5.C: New test. * g++.target/aarch64/mv-error6.C: New test. * g++.target/aarch64/mv-error7.C: New test. * g++.target/aarch64/mv-error8.C: New test. * g++.target/aarch64/mvc-error1.C: New test. * g++.target/aarch64/mvc-error2.C: New test. * g++.target/aarch64/mvc-warning1.C: Modified test. Diff: --- gcc/cp/decl.cc | 7 +++++-- .../g++.target/aarch64/mv-and-mvc-error1.C | 10 ++++++++++ .../g++.target/aarch64/mv-and-mvc-error2.C | 10 ++++++++++ .../g++.target/aarch64/mv-and-mvc-error3.C | 9 +++++++++ gcc/testsuite/g++.target/aarch64/mv-error1.C | 19 +++++++++++++++++++ gcc/testsuite/g++.target/aarch64/mv-error2.C | 10 ++++++++++ gcc/testsuite/g++.target/aarch64/mv-error3.C | 13 +++++++++++++ gcc/testsuite/g++.target/aarch64/mv-error4.C | 10 ++++++++++ gcc/testsuite/g++.target/aarch64/mv-error5.C | 9 +++++++++ gcc/testsuite/g++.target/aarch64/mv-error6.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.target/aarch64/mv-error7.C | 12 ++++++++++++ gcc/testsuite/g++.target/aarch64/mv-error8.C | 13 +++++++++++++ gcc/testsuite/g++.target/aarch64/mvc-error1.C | 10 ++++++++++ gcc/testsuite/g++.target/aarch64/mvc-error2.C | 10 ++++++++++ gcc/testsuite/g++.target/aarch64/mvc-warning1.C | 12 ++++++++++-- 15 files changed, 171 insertions(+), 4 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index c53a8ac4567a..c20af9bc322a 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2022,8 +2022,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) } /* For function versions, params and types match, but they are not ambiguous. */ - else if ((!DECL_FUNCTION_VERSIONED (newdecl) - && !DECL_FUNCTION_VERSIONED (olddecl)) + else if (((!DECL_FUNCTION_VERSIONED (newdecl) + && !DECL_FUNCTION_VERSIONED (olddecl)) + || !comptypes (TREE_TYPE (TREE_TYPE (newdecl)), + TREE_TYPE (TREE_TYPE (olddecl)), + COMPARE_STRICT)) /* Let constrained hidden friends coexist for now, we'll check satisfaction later. */ && !member_like_constrained_friend_p (newdecl) diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C new file mode 100644 index 000000000000..00d3826f757f --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo () { return 3; } /* { dg-message "previous definition" } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) int +foo () { return 1; } /* { dg-error "conflicting .dotprod. versions" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C new file mode 100644 index 000000000000..bf8a4112a216 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("default"))) int +foo () { return 1; } /* { dg-message "old declaration" } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "ambiguating new declaration of" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C new file mode 100644 index 000000000000..3233a98d1ad9 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +float foo () { return 1; } /* { dg-message "previous definition" } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "conflicting .default. versions" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error1.C b/gcc/testsuite/g++.target/aarch64/mv-error1.C new file mode 100644 index 000000000000..0b9642c9ab64 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error1.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("default"))) int +foo (); + +__attribute__ ((target_version ("default"))) int +foo () { return 1; } /* { dg-message "old declaration" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-error "ambiguating new declaration of" } */ + +__attribute__ ((target_version ("sve"))) int +foo2 () { return 1; } /* { dg-message "old declaration" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo2 () { return 3; } /* { dg-error "ambiguating new declaration of" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error2.C b/gcc/testsuite/g++.target/aarch64/mv-error2.C new file mode 100644 index 000000000000..167af4ad380d --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error2.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-message "previously defined here" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-error "redefinition of" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error3.C b/gcc/testsuite/g++.target/aarch64/mv-error3.C new file mode 100644 index 000000000000..cc6414882639 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error3.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } + +__attribute__ ((target_version ("default"))) float +foo () { return 3; } /* { dg-message "previously defined here" } */ + +__attribute__ ((target_version ("default"))) float +foo () { return 3; } /* { dg-error "redefinition of" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error4.C b/gcc/testsuite/g++.target/aarch64/mv-error4.C new file mode 100644 index 000000000000..a6b57a73c3ed --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error4.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("test"))) float +foo () { return 3; } /* { dg-error "invalid feature modifier .test. of value .test. in .target_version. attribute" } */ + +__attribute__ ((target_version ("sve+test"))) float +foo2 () { return 3; } /* { dg-error "invalid feature modifier .test. of value .sve.test. in .target_version. attribute" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error5.C b/gcc/testsuite/g++.target/aarch64/mv-error5.C new file mode 100644 index 000000000000..3d2c73446beb --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error5.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo(); + +int bar () { return foo (); } /* { dg-error "no default version in scope" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error6.C b/gcc/testsuite/g++.target/aarch64/mv-error6.C new file mode 100644 index 000000000000..8ea267504802 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error6.C @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo () { + return 1; +} + +__attribute__ ((target_version ("sve"))) int +foo () { + return 1; +} + +int bar () { return foo (); } /* { dg-error "no matching function for call to" } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo2(); + +int bar2 () { return foo2 (); } /* { dg-error "no default version in scope" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error7.C b/gcc/testsuite/g++.target/aarch64/mv-error7.C new file mode 100644 index 000000000000..c1b58edca11d --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error7.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +int bar () { return foo (); } /* { dg-error "no matching function for call to" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mv-error8.C b/gcc/testsuite/g++.target/aarch64/mv-error8.C new file mode 100644 index 000000000000..0b6b38ce1000 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-error8.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +int +bar () +{ + return foo (); /* { dg-error "no default version in scope" } */ +} diff --git a/gcc/testsuite/g++.target/aarch64/mvc-error1.C b/gcc/testsuite/g++.target/aarch64/mvc-error1.C new file mode 100644 index 000000000000..db6f5a40b391 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mvc-error1.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_clones ("default, dotprod"))) float +foo (); /* { dg-message "previous definition" } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "conflicting .dotprod. versions" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mvc-error2.C b/gcc/testsuite/g++.target/aarch64/mvc-error2.C new file mode 100644 index 000000000000..157086d439d3 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mvc-error2.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ + +__attribute__ ((target_clones ("default, dotprod"))) float +foo () { return 3; } /* { dg-message "previous definition" } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "conflicting .dotprod. versions" } */ diff --git a/gcc/testsuite/g++.target/aarch64/mvc-warning1.C b/gcc/testsuite/g++.target/aarch64/mvc-warning1.C index 59acec3fad2f..b6fb2840ab63 100644 --- a/gcc/testsuite/g++.target/aarch64/mvc-warning1.C +++ b/gcc/testsuite/g++.target/aarch64/mvc-warning1.C @@ -1,6 +1,14 @@ /* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O0" } */ +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ -__attribute__((target_clones("default", "sve"))) -int foo () { return 1; }/* { dg-warning "Function Multi Versioning support is experimental, and the behavior is likely to change" } */ +__attribute__((target_clones("default", "dotprod", "sve+sve2"))) +int foo () { + return 1; +} + +__attribute__((target_clones("invalid1"))) +int foo () { /* { dg-warning "invalid .target_clones. version .invalid1. ignored" } */ + return 2; +}