diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-09-09 12:29:05 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-09-09 12:37:21 -0700 |
commit | 749476b4be1f8ddf482910f907a5b56eb5f3e138 (patch) | |
tree | 971fc51a9c76424446a0db3066a7fafcc6643c0b /gcc | |
parent | 782d3ea603c9ad26176136ffb39481a720246be1 (diff) | |
download | gcc-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.c | 22 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 |
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); |