https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119864

--- Comment #17 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
(In reply to Alberto from comment #16)
> Hello
> 
> Based on your comments I've tried:
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index f642900d12a..c5c97ebc1f3 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -53208,6 +53208,14 @@ cp_parser_omp_declare_reduction (cp_parser *parser,
> cp_token *pragma_tok,
>           block_scope = true;
>           DECL_CONTEXT (fndecl) = current_function_decl;
>           DECL_LOCAL_DECL_P (fndecl) = true;
> +         tree body = DECL_SAVED_TREE (current_function_decl);
> +         if (body && TREE_CODE (body) == BIND_EXPR)
> +           body = BIND_EXPR_BODY (body);
> +         if (body && TREE_CODE (body) == BLOCK)
> +           {
> +             DECL_CHAIN (fndecl) = BLOCK_VARS (body);
> +             BLOCK_VARS (body) = fndecl;
> +           }
>         }
>  
>        if (processing_template_decl)
> 
> but I'm still getting an ICE:
> 
> /home/alberto/gcc-16/gcc-16/bin/g++ -std=c++23 -fmodules -fopenmp
> -fmodule-only -fsearch-include-path bits/std.cc -c
> /home/alberto/gcc-16/gcc-16/include/c++/16.0.0/bits/std.cc:40:8: internal
> compiler error: in decl_node, at cp/module.cc:9115
>    40 | export module std;
>       |        ^~~~~~
> 0x2858cdb internal_error(char const*, ...)
>         ../../gcc/gcc/diagnostic-global-context.cc:787
> 0xaa58e5 fancy_abort(char const*, int, char const*)
>         ../../gcc/gcc/diagnostics/context.cc:1806
> 0x7f08f3 decl_node
>         ../../gcc/gcc/cp/module.cc:9115
> [snip]

Thanks for taking a look!  This doesn't look right (for one, the block vars
should be on DECL_INITIAL of the current function, and it won't actually exist
until the function finishes and current_binding_level->names gets added).  But
investigating this helped me notice something that looks suspicious that
appears to fix the issue.

With the following patch the testcase in comment #0 at least builds correctly,
though I haven't checked if it runs yet...  I also haven't run any regressions
to see if this breaks anything else.

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 0610ee5f65a..e877c6cef81 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12995,7 +12995,13 @@ trees_in::read_function_def (tree decl, tree
maybe_template)
         SET_DECL_FRIEND_CONTEXT (decl, context);
       if (cexpr.decl)
         register_constexpr_fundef (cexpr);
-      post_process (pdata);
+
+      if (DECL_FUNCTION_SCOPE_P (decl))
+        /* Block-scope OMP UDRs aren't real functions and don't need a
+           struct_function to be allocated or to be expanded.  */
+        gcc_checking_assert (DECL_OMP_DECLARE_REDUCTION_P (decl));
+      else
+        post_process (pdata);
     }
   else if (maybe_dup)
     {
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f642900d12a..8bc639148c0 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -53214,10 +53214,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser,
cp_token *pragma_tok,
         fndecl = push_template_decl (fndecl);

       if (block_scope)
-        {
-          if (!processing_template_decl)
-            pushdecl (fndecl);
-        }
+        pushdecl (fndecl);
       else if (current_class_type)
         {
           if (cp == NULL)

Reply via email to