[gcc/devel/omp/gcc-16] OpenMP/C++: Force location wrapper on 'omp allocate' directive clauses

Sandra Loosemore via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:096ae36e308931256146741666a4cd27fe67d89e

commit 096ae36e308931256146741666a4cd27fe67d89e
Author: Waffl3x <[email protected]>
Date:   Tue May 5 09:01:59 2026 -0600

    OpenMP/C++: Force location wrapper on 'omp allocate' directive clauses
    
    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]>

Diff:
---
 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 33c5d0d6122e..952d7754cfcd 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -47683,13 +47683,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 2cc96cf939d7..d2fed059c72d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -20482,11 +20482,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 e0f3bcc17802..27f739df6a54 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 d40288d957d5..a622adc34d92 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 e265ecdd1e74..93777d611eaa 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 } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.