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 } */
