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