Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

There were two issues preventing OpenMP reductions of UDTs from working
in modules.

Firstly, we were failing a number of checking asserts in the streaming
logic because the declaration is a DECL_LOCAL_DECL_P but was not
correctly added to the BLOCK of the function template.  This is because
cp_parser_omp_declare_reduction only called pushdecl when
!processing_template_decl; correcting this fixed this issue.

The second issue is that modules saw this as a function definition and
so attempted to call allocate_struct_function on it, which crashes.
Given that these reduction functions don't really behave like real
function definitions in any other way, I think the cleanest solution is
to just skip all the function definition post-processing in modules;
this seems to work to get the test functioning correctly, from what I
can see.

        PR c++/119864

gcc/cp/ChangeLog:

        * module.cc (trees_in::read_function_def): Don't call
        post_process on OpenMP UDT reductions.
        * parser.cc (cp_parser_omp_declare_reduction): Call push_decl
        for block_scope, even when processing_template_decl.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/omp-4_a.C: New test.
        * g++.dg/modules/omp-4_b.C: New test.

Signed-off-by: Nathaniel Shead <[email protected]>
---
 gcc/cp/module.cc                       |  8 ++++++-
 gcc/cp/parser.cc                       |  5 +----
 gcc/testsuite/g++.dg/modules/omp-4_a.C | 30 ++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/modules/omp-4_b.C | 11 ++++++++++
 4 files changed, 49 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/omp-4_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/omp-4_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ccabd640757..66c7322a6e6 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12985,7 +12985,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_LOCAL_DECL_P (decl))
+       /* Block-scope OMP UDRs aren't real functions, and don't need a
+          function structure 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 06cba31ada6..2f8d7712dc6 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -53170,10 +53170,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)
diff --git a/gcc/testsuite/g++.dg/modules/omp-4_a.C 
b/gcc/testsuite/g++.dg/modules/omp-4_a.C
new file mode 100644
index 00000000000..948966e657f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/omp-4_a.C
@@ -0,0 +1,30 @@
+// PR c++/119864
+// { dg-additional-options "-fmodules -fopenmp" }
+// { dg-module-cmi p1 }
+
+export module p1;
+
+export
+template<unsigned>
+struct T
+{
+  double d;
+
+  T &operator +=(T const &x) { d += x.d; return *this; }
+};
+
+export
+template<unsigned d>
+T<d> sum(T<d> const *p, unsigned N)
+{
+T<d> Sum = {};
+
+#pragma omp declare reduction(Op: T<d>: omp_out += omp_in) 
initializer(omp_priv = {})
+#pragma omp parallel for reduction(Op: Sum)
+for (unsigned i = 0u; i < N; ++i)
+  {
+  Sum += *p;
+  ++p;
+  }
+return Sum;
+}
diff --git a/gcc/testsuite/g++.dg/modules/omp-4_b.C 
b/gcc/testsuite/g++.dg/modules/omp-4_b.C
new file mode 100644
index 00000000000..c1ca279a97e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/omp-4_b.C
@@ -0,0 +1,11 @@
+// PR c++/119864
+// { dg-additional-options "-fmodules -fopenmp" }
+
+import p1;
+
+int main()
+{
+  T<1u> v[3u] = {};
+
+  T s = sum(v, 3u);
+}
-- 
2.51.0

Reply via email to