[committed] openmp: Return error_mark_node from tsubst_attribute for errneous varid

Message ID ZyTQUI0yopCJgVy3@tucnak
State New
Headers
Series [committed] openmp: Return error_mark_node from tsubst_attribute for errneous varid |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jakub Jelinek Nov. 1, 2024, 12:57 p.m. UTC
  Hi!

We incorrectly accept some invalid declare variant cases as if declare
variant wasn't there, in particular if a function template has some dependent
arguments and variant name lookup fails, because that is during
fn_type_unification with complain=tf_none, it just sets it to error_mark_node
and doesn't complain further, because it doesn't know the substitution failed
(we don't return error_mark_node from tsubst_attribute, just create TREE_LIST
with error_mark_node TREE_PURPOSE).

The following patch fixes it by returning error_mark_node in that case, then
fn_type_unification caller can see it failed and can redo it with explain_p
so that errors are reported.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2024-11-01  Jakub Jelinek  <jakub@redhat.com>

	* pt.cc (tsubst_attribute): For "omp declare variant base" attribute
	if varid is error_mark_node, set val to error_mark_node rather than
	creating a TREE_LIST with error_mark_node TREE_PURPOSE.

	* g++.dg/gomp/declare-variant-10.C: New test.


	Jakub
  

Patch

--- gcc/cp/pt.cc.jj	2024-10-25 10:00:29.431768386 +0200
+++ gcc/cp/pt.cc	2024-10-31 10:57:05.855001910 +0100
@@ -12163,7 +12163,10 @@  tsubst_attribute (tree t, tree *decl_p,
 	    }
 	  OMP_TSS_TRAIT_SELECTORS (tss) = nreverse (selectors);
 	}
-      val = tree_cons (varid, ctx, chain);
+      if (varid == error_mark_node)
+	val = error_mark_node;
+      else
+	val = tree_cons (varid, ctx, chain);
     }
   /* If the first attribute argument is an identifier, don't
      pass it through tsubst.  Attributes like mode, format,
--- gcc/testsuite/g++.dg/gomp/declare-variant-10.C.jj	2024-10-31 11:21:13.962820634 +0100
+++ gcc/testsuite/g++.dg/gomp/declare-variant-10.C	2024-10-31 11:26:59.651011406 +0100
@@ -0,0 +1,56 @@ 
+// { dg-do compile }
+
+#pragma omp declare variant (f1) match(user={condition(1)})	// { dg-error "'f1' was not declared in this scope; did you mean 'f2'\\\?" }
+void
+f2 (int)
+{
+}
+
+void f3 (int);
+
+#pragma omp declare variant (f3) match(user={condition(1)})	// { dg-error "variant 'void f3\\\(int\\\)' and base 'void f4\\\(long int\\\)' have incompatible types" }
+void
+f4 (long)
+{
+}
+
+#pragma omp declare variant (f5) match(user={condition(1)})	// { dg-error "there are no arguments to 'f5' that depend on a template parameter, so a declaration of 'f5' must be available" }
+template <int N>
+void
+f6 (int)
+{
+}
+
+template <int N>
+void f7 (int);
+
+#pragma omp declare variant (f7) match(user={condition(1)})	// { dg-error "no matching function for call to 'f7\\\(long int\\\)'" }
+template <int N>
+void
+f8 (long)
+{
+}
+
+#pragma omp declare variant (f9) match(user={condition(1)})
+template <typename T>
+void
+f10 (T)								// { dg-error "'f9' was not declared in this scope; did you mean 'f8'\\\?" }
+{
+}
+
+template <typename T>
+void f11 (T, int);
+
+#pragma omp declare variant (f11) match(user={condition(1)})	// { dg-error "variant 'void f11\\\(T, int\\\) \\\[with T = int\\\]' and base 'void f12\\\(T, long int\\\) \\\[with T = int\\\]' have incompatible types" }
+template <typename T>
+void
+f12 (T, long)
+{
+}
+
+void
+test ()
+{
+  f10 (0);							// { dg-error "no matching function for call to 'f10\\\(int\\\)'" }
+  f12 (0, 0L);
+}