aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-09-09 12:29:05 -0700
committerNathan Sidwell <nathan@acm.org>2020-09-09 12:37:21 -0700
commit749476b4be1f8ddf482910f907a5b56eb5f3e138 (patch)
tree971fc51a9c76424446a0db3066a7fafcc6643c0b /gcc
parent782d3ea603c9ad26176136ffb39481a720246be1 (diff)
downloadgcc-749476b4be1f8ddf482910f907a5b56eb5f3e138.zip
gcc-749476b4be1f8ddf482910f907a5b56eb5f3e138.tar.gz
gcc-749476b4be1f8ddf482910f907a5b56eb5f3e138.tar.bz2
c++: omp reduction cleanups
omp reductions are modeled as nested functions, which is a thing C++ doesn't have. Leading to much confusion until I figured out what was happening. Not helped by some duplicate code and inconsistencies in the dependent and non-dependent paths. This patch removes the parser duplication and fixes up some bookkeeping. Added some asserts and comments too. gcc/cp/ * parser.c (cp_parser_omp_declare_reduction): Refactor to avoid code duplication. Update DECL_TI_TEMPLATE's context. * pt.c (tsubst_expr): For OMP reduction function, set context to global_namespace before pushing. (tsubst_omp_udr): Assert current_function_decl, add comment about decl context.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.c22
-rw-r--r--gcc/cp/pt.c9
2 files changed, 19 insertions, 12 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9849e59..0da3839 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -42616,16 +42616,9 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
cp_parser_push_lexer_for_tokens (parser, cp);
parser->lexer->in_pragma = true;
}
- if (!cp_parser_omp_declare_reduction_exprs (fndecl, parser))
- {
- if (!block_scope)
- finish_function (/*inline_p=*/false);
- else
- DECL_CONTEXT (fndecl) = current_function_decl;
- if (cp)
- cp_parser_pop_lexer (parser);
- goto fail;
- }
+
+ bool ok = cp_parser_omp_declare_reduction_exprs (fndecl, parser);
+
if (cp)
cp_parser_pop_lexer (parser);
if (!block_scope)
@@ -42633,6 +42626,14 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
else
{
DECL_CONTEXT (fndecl) = current_function_decl;
+ if (DECL_TEMPLATE_INFO (fndecl))
+ DECL_CONTEXT (DECL_TI_TEMPLATE (fndecl)) = current_function_decl;
+ }
+ if (!ok)
+ goto fail;
+
+ if (block_scope)
+ {
block = finish_omp_structured_block (block);
if (TREE_CODE (block) == BIND_EXPR)
DECL_SAVED_TREE (fndecl) = BIND_EXPR_BODY (block);
@@ -42641,6 +42642,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
if (processing_template_decl)
add_decl_expr (fndecl);
}
+
cp_check_omp_declare_reduction (fndecl);
if (cp == NULL && types.length () > 1)
cp = cp_token_cache_new (first_token,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a7b7a12..4e21262 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18077,7 +18077,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
&& DECL_OMP_DECLARE_REDUCTION_P (decl)
&& DECL_FUNCTION_SCOPE_P (pattern_decl))
{
- DECL_CONTEXT (decl) = NULL_TREE;
+ /* We pretend this is regular local extern decl of
+ a namespace-scope fn. Then we make it really
+ local, it is a nested function. */
+ DECL_CONTEXT (decl) = global_namespace;
pushdecl (decl);
DECL_CONTEXT (decl) = current_function_decl;
cp_check_omp_declare_reduction (decl);
@@ -18899,7 +18902,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (t == NULL_TREE || t == error_mark_node)
return;
- gcc_assert (TREE_CODE (t) == STATEMENT_LIST);
+ gcc_assert (TREE_CODE (t) == STATEMENT_LIST && current_function_decl);
tree_stmt_iterator tsi;
int i;
@@ -18919,6 +18922,8 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
args, complain, in_decl);
tree omp_in = tsubst (DECL_EXPR_DECL (stmts[1]),
args, complain, in_decl);
+ /* tsubsting a local var_decl leaves DECL_CONTEXT null, as we
+ expect to be pushing it. */
DECL_CONTEXT (omp_out) = current_function_decl;
DECL_CONTEXT (omp_in) = current_function_decl;
keep_next_level (true);