]> gcc.gnu.org Git - gcc.git/commitdiff
c++: omp reduction cleanups
authorNathan Sidwell <nathan@acm.org>
Wed, 9 Sep 2020 19:29:05 +0000 (12:29 -0700)
committerNathan Sidwell <nathan@acm.org>
Wed, 9 Sep 2020 19:37:21 +0000 (12:37 -0700)
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.

gcc/cp/parser.c
gcc/cp/pt.c

index 9849e59d5aa4a0aa06712e2568a903533035cf7b..0da383937c216b263c577cceb3132ab1be27eda2 100644 (file)
@@ -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,
index a7b7a12b59f3f4582056960a9c34a882ee0e3606..4e212620eaf061087383c2551329d0cca9c8e06d 100644 (file)
@@ -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);
This page took 0.119289 seconds and 5 git commands to generate.