Some nodes, such as template parameters, don't get wrapped by
maybe_wrap_with_location. We rely on location wrappers for diagnostics of
clause exprs in finish_omp_allocate, the easiest solution is to force a
wrapper by replicating the the mechanisms of maybe_wrap_with_location in
cp_parser_omp_allocate.

Unfortuntely, tsubst_expr uses maybe_wrap_with_location to rewrap location
wrappers, stripping wrappers that we previously forced. This patch solves
that by handling wrappers explicitly in tsubst_expr's OMP_ALLOCATE case.

This is kind of a kludge, if this is deemed to be a good solution we should
possibly split it out into its own function (force_wrap_with_location?) and
change tsubst_expr to use that for rewrapping. This would be trivial to do,
but belongs in a different patch.

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_omp_allocate): Force a location wrapper.
        * pt.cc (tsubst_stmt): Rewrap location wrappers after tsubst_expr.

gcc/testsuite/ChangeLog:

        * g++.dg/gomp/allocate-10.C: Remove xfails.
        * g++.dg/gomp/allocate-14.C: Likewise.
        * g++.dg/gomp/allocate-17.C: Likewise.

Signed-off-by: Waffl3x <[email protected]>
---
 gcc/cp/parser.cc                        | 26 +++++++++++++++--
 gcc/cp/pt.cc                            | 24 ++++++++++++----
 gcc/testsuite/g++.dg/gomp/allocate-10.C | 12 +++-----
 gcc/testsuite/g++.dg/gomp/allocate-14.C | 37 +++++++++++--------------
 gcc/testsuite/g++.dg/gomp/allocate-17.C | 23 +++++++--------
 5 files changed, 73 insertions(+), 49 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 924e52da6ea..412a71c439c 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -47373,13 +47373,35 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token 
*pragma_tok)
     } while (true);
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
+  /* Some codes, such as template parameters, don't get wrapped by
+     maybe_wrap_with_location despite not being able to carry a location.
+     We need a location to issue good diagnostics in finish_omp_allocate.  */
+  auto maybe_force_wrap_with_location = [] (cp_expr expr_with_loc) -> tree
+    {
+      tree expr = expr_with_loc.get_value ();
+      if (!expr || error_operand_p (expr))
+       return expr;
+      /* In most situations, expr will already have been wrapped.  */
+      if (CAN_HAVE_LOCATION_P (expr))
+       return expr;
+
+      location_t expr_loc = expr_with_loc.get_location ();
+      /* Copied from tree.cc:maybe_wrap_with_location.  */
+      const tree_code code
+       = (((CONSTANT_CLASS_P (expr) && TREE_CODE (expr) != STRING_CST)
+           || (TREE_CODE (expr) == CONST_DECL && !TREE_STATIC (expr)))
+          ? NON_LVALUE_EXPR : VIEW_CONVERT_EXPR);
+      tree wrapper = build1_loc (expr_loc, code, TREE_TYPE (expr), expr);
+      EXPR_LOCATION_WRAPPER_P (wrapper) = 1;
+      return wrapper;
+    };
   /* We can still diagnose some things about allocator/alignment even if nl
      is NULL_TREE.  */
 
   finish_omp_allocate (pragma_tok->location,
                       nl,
-                      allocator,
-                      alignment,
+                      maybe_force_wrap_with_location (allocator),
+                      maybe_force_wrap_with_location (alignment),
                       directive_ctx);
 }
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index aa41a46e007..d27f3c1118f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -20469,11 +20469,25 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
     case OMP_ALLOCATE:
       {
        gcc_assert (flag_openmp);
-
-       tree alloc
-         = tsubst_expr (OMP_ALLOCATE_ALLOCATOR (t), args, complain, in_decl);
-       tree align
-         = tsubst_expr (OMP_ALLOCATE_ALIGN (t), args, complain, in_decl);
+       /* We force a location wrapper in some cases that don't get wrapped by
+          maybe_wrap_with_location, tsubst_expr doesn't rewrap them in those
+          cases so we have to do it.  */
+       auto subst_and_rewrap = [&] (const tree expr)
+         {
+           if (!expr || expr == error_mark_node)
+             return expr;
+           tree ret = tsubst_expr (tree_strip_any_location_wrapper (expr),
+                                   args, complain, in_decl);
+           if (location_wrapper_p (expr) && !CAN_HAVE_LOCATION_P (ret))
+             {
+               ret = build1_loc (EXPR_LOCATION (expr), TREE_CODE (expr),
+                                 TREE_TYPE (ret), ret);
+               EXPR_LOCATION_WRAPPER_P (ret) = 1;
+             }
+           return ret;
+         };
+       tree alloc = subst_and_rewrap (OMP_ALLOCATE_ALLOCATOR (t));
+       tree align = subst_and_rewrap (OMP_ALLOCATE_ALIGN (t));
        tree vars = copy_list (OMP_ALLOCATE_VARS (t));
        for (tree node = vars; node != NULL_TREE; node = TREE_CHAIN (node))
          {
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-10.C 
b/gcc/testsuite/g++.dg/gomp/allocate-10.C
index e0f3bcc1780..27f739df6a5 100644
--- a/gcc/testsuite/g++.dg/gomp/allocate-10.C
+++ b/gcc/testsuite/g++.dg/gomp/allocate-10.C
@@ -34,7 +34,7 @@ void auto_nttp_allocator_static_0()
   static int a;
   #pragma omp allocate(a) allocator(Alloc)
   /* { dg-error "invalid conversion from 'int' to 'omp_allocator_handle_t'" "" 
{ target *-*-* } .-1 } */
-  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { xfail *-*-* } .-2 } */
+  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { target *-*-* } .-2 } */
 }
 
 template<auto Alloc>
@@ -49,7 +49,7 @@ void auto_nttp_allocator_static_2()
 {
   static int a;
   #pragma omp allocate(a) allocator(Alloc)
-  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { xfail *-*-* } .-1 } */
+  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { target *-*-* } .-1 } */
 }
 
 template<auto Alloc>
@@ -76,8 +76,6 @@ void instantiate_auto_nttp_allocator_static()
 
 #undef DEFINITELY_NOT_PREDEFINED
 
-/* { dg-bogus "'allocator' clause requires a constant predefined allocator" "" 
{ xfail *-*-* } 0 } */
-
 /* Invalid align clause */
 
 template<auto Align>
@@ -91,7 +89,7 @@ template<auto Align>
 void auto_nttp_align_0()
 {
   int a;
-  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" "" { xfail *-*-* 
} } */
+  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" "" { target 
*-*-* } } */
 }
 
 template<auto Align>
@@ -99,7 +97,7 @@ void auto_nttp_align_1()
 {
   int a;
   #pragma omp allocate(a) align(Align)
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
   /* { dg-error {could not convert 'nullptr' from 'std::nullptr_t' to '(?:long 
)?unsigned int'} "" { target *-*-* } .-2 } */
 }
 
@@ -111,5 +109,3 @@ void instantiate_auto_nttp_align()
   auto_nttp_align_1<32>(); /* { dg-bogus "required from here" } */
   auto_nttp_align_1<nullptr>(); /* { dg-message "required from here" } */
 }
-
-/* { dg-bogus "'align' clause argument needs to be positive constant power of 
two integer expression" "" { xfail *-*-* } 0 } */
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-14.C 
b/gcc/testsuite/g++.dg/gomp/allocate-14.C
index d40288d957d..a622adc34d9 100644
--- a/gcc/testsuite/g++.dg/gomp/allocate-14.C
+++ b/gcc/testsuite/g++.dg/gomp/allocate-14.C
@@ -121,9 +121,9 @@ void nttp_allocator_static()
 {
   static int a; /* { dg-note "'a' declared here" } */
   #pragma omp allocate(a) allocator(Alloc)
-  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { xfail *-*-* } .-1 } */
+  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { target *-*-* } .-1 } */
   /* { dg-note "because one or more variables with static storage duration 
appear in the 'allocate' directive" "" { target *-*-* } .-2 } */
-  /* { dg-note "expression evaluates to '1024'" "" { xfail *-*-* } .-3 }*/
+  /* { dg-note "expression evaluates to '1024'" "" { target *-*-* } .-3 }*/
 }
 
 template<omp_allocator_handle_t Alloc>
@@ -145,9 +145,9 @@ void nttp_dependent_type_allocator_static_0()
 {
   static int a; /* { dg-note "'a' declared here" } */
   #pragma omp allocate(a) allocator(Alloc)
-  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { xfail *-*-* } .-1 } */
+  /* { dg-error "'allocator' clause requires a constant predefined allocator" 
"" { target *-*-* } .-1 } */
   /* { dg-note "because one or more variables with static storage duration 
appear in the 'allocate' directive" "" { target *-*-* } .-2 } */
-  /* { dg-note "expression evaluates to '1024'" "" { xfail *-*-* } .-3 }*/
+  /* { dg-note "expression evaluates to '1024'" "" { target *-*-* } .-3 }*/
 }
 
 template<typename AllocT, AllocT Alloc>
@@ -266,7 +266,7 @@ template<int Align>
 void nttp_align()
 {
   int a;
-  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" "" { xfail *-*-* 
} } */
+  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" } */
 }
 
 template<int Align>
@@ -289,7 +289,7 @@ template<typename AlignT, AlignT Align>
 void nttp_dependent_type_align_0()
 {
   int a;
-  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" "" { xfail *-*-* 
} } */
+  #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause argument 
needs to be positive constant power of two integer expression" } */
 }
 
 template<typename AlignT, AlignT Align>
@@ -420,7 +420,7 @@ void all_dependent_2()
   int b = 42;
   Var a = b;
   #pragma omp allocate(a) allocator(Alloc) align(Align)
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
 }
 
 template<typename Var,
@@ -444,7 +444,7 @@ void all_dependent_4()
   Var a = b; /* { dg-note "'a' declared here" } */
   #pragma omp allocate(a) allocator(Alloc) align(Align)
   /* { dg-error "variables with reference type may not appear in an 'allocate' 
directive" "" { target *-*-* } .-1 } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-2 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-2 } */
 }
 
 template<typename Var,
@@ -456,7 +456,7 @@ void all_dependent_5()
   Var a = b;
   #pragma omp allocate(a) allocator(Alloc) align(Align)
   /* { dg-error "invalid conversion from 'int' to 'omp_allocator_handle_t'" "" 
{ target *-*-* } .-1 } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-2 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-2 } */
 }
 
 template<typename Var,
@@ -469,7 +469,7 @@ void all_dependent_6()
   #pragma omp allocate(a) allocator(Alloc) align(Align)
   /* { dg-error "variables with reference type may not appear in an 'allocate' 
directive" "" { target *-*-* } .-1 } */
   /* { dg-error "invalid conversion from 'int' to 'omp_allocator_handle_t'" "" 
{ target *-*-* } .-2 } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-3 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-3 } */
 }
 
 void instantiate_all_dependent()
@@ -603,7 +603,7 @@ template<int Align>
 void templ_no_vars_dep_align_invalid()
 {
   #pragma omp allocate() align(Align) /* { dg-error "expected unqualified-id 
before '\\\)' token" } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
 }
 template void templ_no_vars_dep_align_invalid<42>();
 
@@ -876,7 +876,7 @@ template<int Align>
 void templ_invalid_vars_param_dependent_align_invalid(int p) /* { dg-note 
"parameter 'p' declared here" } */
 {
   #pragma omp allocate(p) align(Align) /* { dg-error "function parameter 'p' 
may not appear as list item in an 'allocate' directive" } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
 }
 template void templ_invalid_vars_param_dependent_align_invalid<42>(int);
 
@@ -908,7 +908,7 @@ void 
templ_invalid_vars_out_of_scope_dependent_align_invalid()
   int a; /* { dg-note "declared here" } */
   {
     #pragma omp allocate(a) align(Align) /* { dg-error "'allocate' directive 
must be in the same scope as 'a'" } */
-    /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+    /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
   }
 }
 template void templ_invalid_vars_out_of_scope_dependent_align_invalid<42>();
@@ -944,7 +944,7 @@ void 
templ_invalid_vars_out_of_scope_and_param_dependent_align_invalid(int p) /*
   {
     #pragma omp allocate(a, p) align(Align) /* { dg-error "'allocate' 
directive must be in the same scope as 'a'" } */
     /* { dg-error "function parameter 'p' may not appear as list item in an 
'allocate' directive" "" { target *-*-* } .-1 } */
-    /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-2 } */
+    /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-2 } */
   }
 }
 template void 
templ_invalid_vars_out_of_scope_and_param_dependent_align_invalid<42>(int);
@@ -1001,7 +1001,7 @@ void multiple_uses_dep_directive_before_invalid_align()
 {
   int a;
   #pragma omp allocate(a) align(Align) /* { dg-note "'a' previously appeared 
here" } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
   #pragma omp allocate(a) /* { dg-error "'a' already appeared as list item in 
an 'allocate' directive" } */
 }
 template void multiple_uses_dep_directive_before_invalid_align<42>();
@@ -1032,11 +1032,6 @@ void multiple_uses_dep_directive_after_invalid_align()
   int a;
   #pragma omp allocate(a) /* { dg-note "'a' previously appeared here" } */
   #pragma omp allocate(a) align(Align) /* { dg-error "'a' already appeared as 
list item in an 'allocate' directive" } */
-  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { xfail *-*-* } .-1 } */
+  /* { dg-error "'align' clause argument needs to be positive constant power 
of two integer expression" "" { target *-*-* } .-1 } */
 }
 template void multiple_uses_dep_directive_after_invalid_align<42>();
-
-/* These are fixed by the later location wrapping patch.  */
-/* { dg-bogus "'align' clause argument needs to be positive constant power of 
two integer expression" "" { xfail *-*-* } 0 } */
-/* { dg-bogus "'allocator' clause requires a constant predefined allocator" "" 
{ xfail *-*-* } 0 } */
-/* { dg-bogus "expression evaluates to '1024'" "" { xfail *-*-* } 0 } */
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-17.C 
b/gcc/testsuite/g++.dg/gomp/allocate-17.C
index e265ecdd1e7..93777d611ea 100644
--- a/gcc/testsuite/g++.dg/gomp/allocate-17.C
+++ b/gcc/testsuite/g++.dg/gomp/allocate-17.C
@@ -31,7 +31,7 @@ auto lambda_0_bad_align()
          int b = 42;
          decltype(p3) a = b;
          #pragma omp allocate(a) align(Align) allocator(p2)
-         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { xfail *-*-* } .-1 } */
+         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { target *-*-* } .-1 } */
          return a;
        };
       };
@@ -87,7 +87,7 @@ auto lambda_0_all()
          decltype(p3) a = b; /* { dg-message "'a' declared here" } */
          #pragma omp allocate(a) align(Align) allocator(p2)
          /* { dg-error "variables with reference type may not appear in an 
'allocate' directive" "" { target *-*-* } .-1 } */
-         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { xfail *-*-* } .-2 } */
+         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { target *-*-* } .-2 } */
          /* { dg-error "invalid conversion from 'int' to 
'omp_allocator_handle_t'" "" { target *-*-* } .-3 } */
          return a;
        };
@@ -212,18 +212,18 @@ auto lambda_1_bad_align()
 {
   return [](auto p0){
     int a = 42;
-    #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+    #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
     return [](auto p1){
       int a = 42;
-      #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+      #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
       return [](auto p2){
        int a = 42;
-       #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+       #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
        return [p2](auto p3){
          int b = 42;
          decltype(p3) a = b;
          #pragma omp allocate(a) align(Align) allocator(p2)
-         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { xfail *-*-* } .-1 } */
+         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { target *-*-* } .-1 } */
          return a;
        };
       };
@@ -284,19 +284,19 @@ auto lambda_1_all()
 {
   return [](auto p0){
     int a = 42;
-    #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+    #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
     return [](auto p1){
       int a = 42;
-      #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+      #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
       return [](auto p2){
        int a = 42;
-       #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" "" { 
xfail *-*-* } } */
+       #pragma omp allocate(a) align(Align) /* { dg-error "'align' clause 
argument needs to be positive constant power of two integer expression" } */
        return [p2](auto p3){
          int b = 42;
          decltype(p3) a = b; /* { dg-message "'a' declared here" } */
          #pragma omp allocate(a) align(Align) allocator(p2)
          /* { dg-error "variables with reference type may not appear in an 
'allocate' directive" "" { target *-*-* } .-1 } */
-         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { xfail *-*-* } .-2 } */
+         /* { dg-error "'align' clause argument needs to be positive constant 
power of two integer expression" "" { target *-*-* } .-2 } */
          /* { dg-error "invalid conversion from 'int' to 
'omp_allocator_handle_t'" "" { target *-*-* } .-3 } */
          return a;
        };
@@ -555,6 +555,3 @@ void instantiate_lambdas_2()
     auto c3 = c2.operator()<int&>(a); /* { dg-message "required from here" } */
   }
 }
-
-/* This is fixed by the later location wrapping patch.  */
-/* { dg-bogus "'align' clause argument needs to be positive constant power of 
two integer expression" "" { xfail *-*-* } 0 } */
-- 
2.54.0

Reply via email to