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.
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;
--- /dev/null
+/* { 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" } } */