https://gcc.gnu.org/g:7fdb66f0db6275118986ed8d77c94d6cfe5155c2

commit r15-4836-g7fdb66f0db6275118986ed8d77c94d6cfe5155c2
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Nov 1 11:57:32 2024 +0100

    openmp: Return error_mark_node from tsubst_attribute for errneous varid
    
    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.
    
    2024-11-01  Jakub Jelinek  <ja...@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.

Diff:
---
 gcc/cp/pt.cc                                   |  5 ++-
 gcc/testsuite/g++.dg/gomp/declare-variant-10.C | 56 ++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 15d6d82f32fb..334dbb3c39aa 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -12163,7 +12163,10 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
            }
          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,
diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-10.C 
b/gcc/testsuite/g++.dg/gomp/declare-variant-10.C
new file mode 100644
index 000000000000..282cbc7ad785
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/declare-variant-10.C
@@ -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);
+}

Reply via email to