https://gcc.gnu.org/g:81c0b5f2e49a3890d4c5b547ecd433492136461d
commit 81c0b5f2e49a3890d4c5b547ecd433492136461d Author: Tobias Burnus <tbur...@baylibre.com> Date: Mon Jan 27 12:50:05 2025 +0100 OpenMP/C++: Fix 'declare variant' for struct-returning functions [PR118486] To find the variant declaration, a call is constructed in omp_declare_variant_finalize_one, which gives here: TARGET_EXPR <D.3010, variant_fn ()> Extracting now the function declaration failed and gave the bogus error: could not find variant declaration Solution: Use the 2nd argument of the TARGET_EXPR and continue. PR c++/118486 gcc/cp/ChangeLog: * decl.cc (omp_declare_variant_finalize_one): When resolving the variant to use, handle variant calls with TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/gomp/declare-variant-11.C: New test. (cherry picked from commit b67a0d6aca0c049e14e44c3f28ce3806680543ef) Diff: --- gcc/cp/ChangeLog.omp | 9 ++++++ gcc/cp/decl.cc | 3 ++ gcc/testsuite/ChangeLog.omp | 8 ++++++ gcc/testsuite/g++.dg/gomp/declare-variant-11.C | 38 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp index ae6628104f34..d54c7288a9d3 100644 --- a/gcc/cp/ChangeLog.omp +++ b/gcc/cp/ChangeLog.omp @@ -1,3 +1,12 @@ +2025-01-27 Tobias Burnus <tbur...@baylibre.com> + + Backported from master: + 2025-01-15 Tobias Burnus <tbur...@baylibre.com> + + PR c++/118486 + * decl.cc (omp_declare_variant_finalize_one): When resolving + the variant to use, handle variant calls with TARGET_EXPR. + 2025-01-27 Tobias Burnus <tbur...@baylibre.com> Backported from master: diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index b1f8759cee89..d48b63e63921 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8318,6 +8318,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr) if (variant == error_mark_node && !processing_template_decl) return true; + if (TREE_CODE (variant) == TARGET_EXPR) + variant = TARGET_EXPR_INITIAL (variant); + variant = cp_get_callee_fndecl_nofold (STRIP_REFERENCE_REF (variant)); input_location = save_loc; diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp index 7dd9def7327a..ed535301dd09 100644 --- a/gcc/testsuite/ChangeLog.omp +++ b/gcc/testsuite/ChangeLog.omp @@ -1,3 +1,11 @@ +2025-01-27 Tobias Burnus <tbur...@baylibre.com> + + Backported from master: + 2025-01-15 Tobias Burnus <tbur...@baylibre.com> + + PR c++/118486 + * g++.dg/gomp/declare-variant-11.C: New test. + 2025-01-27 Tobias Burnus <tbur...@baylibre.com> Backported from master: diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-11.C b/gcc/testsuite/g++.dg/gomp/declare-variant-11.C new file mode 100644 index 000000000000..56b2556416c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/declare-variant-11.C @@ -0,0 +1,38 @@ +/* { dg-additional-options "-fdump-tree-gimple" } */ + +/* PR c++/118486 */ + +struct NotAnInt {}; + +// Wrong return type: +NotAnInt var1(); +#pragma omp declare variant(var1) match(user={condition(true)}) +int base1(); +/* { dg-error "variant 'NotAnInt var1\\(\\)' and base 'int base1\\(\\)' have incompatible types" "" { target *-*-* } .-2 } */ + + +// Wrong return type: +NotAnInt var2(); +float var2(float); +#pragma omp declare variant(var2) match(user={condition(true)}) +int base2(); +/* { dg-error "variant 'NotAnInt var2\\(\\)' and base 'int base2\\(\\)' have incompatible types" "" { target *-*-* } .-2 } */ + + +// OK: +NotAnInt var3(); +#pragma omp declare variant(var3) match(user={condition(true)}) +NotAnInt base3(); + +void f() +{ + // int x; + NotAnInt y; + + //x = base1 (); + //x = base2 (); + y = base3 (); +} + +/* { dg-final { scan-tree-dump "var3 \\(\\);" "gimple" } } */ +/* { dg-final { scan-tree-dump-not "base3" "gimple" } } */