From 87b153d0c67c677fbf997e3fa81b793ff99aadd7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 20 Dec 2019 18:30:38 +0100 Subject: [PATCH] backport: re PR c++/60228 (ICE using lambda in #pragma omp declare reduction) Backported from mainline 2019-11-29 Jakub Jelinek PR c++/60228 * parser.c (cp_parser_omp_declare_reduction_exprs): If processing_template_decl, wrap the combiner or initializer into EXPR_STMT. * decl.c (start_preparsed_function): Don't start a lambda scope for DECL_OMP_DECLARE_REDUCTION_P functions. (finish_function): Don't finish a lambda scope for DECL_OMP_DECLARE_REDUCTION_P functions, nor cp_fold_function them nor cp_genericize them. * mangle.c (decl_mangling_context): Look through DECL_OMP_DECLARE_REDUCTION_P functions. * semantics.c (expand_or_defer_fn_1): For DECL_OMP_DECLARE_REDUCTION_P functions, use tentative linkage, don't keep their bodies with -fkeep-inline-functions and return false at the end. * g++.dg/gomp/openmp-simd-2.C: Don't expect bodies for DECL_OMP_DECLARE_REDUCTION_P functions. * testsuite/libgomp.c++/udr-20.C: New test. * testsuite/libgomp.c++/udr-21.C: New test. From-SVN: r279662 --- gcc/cp/ChangeLog | 17 +++++++ gcc/cp/decl.c | 11 +++-- gcc/cp/mangle.c | 11 ++++- gcc/cp/parser.c | 4 ++ gcc/cp/semantics.c | 6 ++- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/gomp/openmp-simd-2.C | 2 - libgomp/ChangeLog | 9 ++++ libgomp/testsuite/libgomp.c++/udr-20.C | 54 +++++++++++++++++++++++ libgomp/testsuite/libgomp.c++/udr-21.C | 54 +++++++++++++++++++++++ 10 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/udr-20.C create mode 100644 libgomp/testsuite/libgomp.c++/udr-21.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d95f679907e2..af8983803107 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,23 @@ 2019-12-20 Jakub Jelinek Backported from mainline + 2019-11-29 Jakub Jelinek + + PR c++/60228 + * parser.c (cp_parser_omp_declare_reduction_exprs): If + processing_template_decl, wrap the combiner or initializer + into EXPR_STMT. + * decl.c (start_preparsed_function): Don't start a lambda scope + for DECL_OMP_DECLARE_REDUCTION_P functions. + (finish_function): Don't finish a lambda scope for + DECL_OMP_DECLARE_REDUCTION_P functions, nor cp_fold_function + them nor cp_genericize them. + * mangle.c (decl_mangling_context): Look through + DECL_OMP_DECLARE_REDUCTION_P functions. + * semantics.c (expand_or_defer_fn_1): For DECL_OMP_DECLARE_REDUCTION_P + functions, use tentative linkage, don't keep their bodies with + -fkeep-inline-functions and return false at the end. + 2019-11-28 Jakub Jelinek PR c++/92695 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 444332e53ba8..f3f20b55c8b5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -15632,7 +15632,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags) && !implicit_default_ctor_p (decl1)) cp_ubsan_maybe_initialize_vtbl_ptrs (current_class_ptr); - start_lambda_scope (decl1); + if (!DECL_OMP_DECLARE_REDUCTION_P (decl1)) + start_lambda_scope (decl1); return true; } @@ -16040,7 +16041,8 @@ finish_function (bool inline_p) if (fndecl == NULL_TREE) return error_mark_node; - finish_lambda_scope (); + if (!DECL_OMP_DECLARE_REDUCTION_P (fndecl)) + finish_lambda_scope (); if (c_dialect_objc ()) objc_finish_function (); @@ -16157,7 +16159,7 @@ finish_function (bool inline_p) invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); /* Perform delayed folding before NRV transformation. */ - if (!processing_template_decl) + if (!processing_template_decl && !DECL_OMP_DECLARE_REDUCTION_P (fndecl)) cp_fold_function (fndecl); /* Set up the named return value optimization, if we can. Candidate @@ -16280,7 +16282,8 @@ finish_function (bool inline_p) if (!processing_template_decl) { struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl); - cp_genericize (fndecl); + if (!DECL_OMP_DECLARE_REDUCTION_P (fndecl)) + cp_genericize (fndecl); /* Clear out the bits we don't need. */ f->x_current_class_ptr = NULL; f->x_current_class_ref = NULL; diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index a5fd66fe0de3..6f1943752613 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -874,7 +874,16 @@ decl_mangling_context (tree decl) else if (template_type_parameter_p (decl)) /* template type parms have no mangling context. */ return NULL_TREE; - return CP_DECL_CONTEXT (decl); + + tcontext = CP_DECL_CONTEXT (decl); + + /* Ignore the artificial declare reduction functions. */ + if (tcontext + && TREE_CODE (tcontext) == FUNCTION_DECL + && DECL_OMP_DECLARE_REDUCTION_P (tcontext)) + return decl_mangling_context (tcontext); + + return tcontext; } /* ::= diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8b5fa4cbd5ff..4df5d5797dc2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -39476,6 +39476,8 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser) combiner = cp_parser_expression (parser); finish_expr_stmt (combiner); block = finish_omp_structured_block (block); + if (processing_template_decl) + block = build_stmt (input_location, EXPR_STMT, block); add_stmt (block); if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) @@ -39580,6 +39582,8 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser) block = finish_omp_structured_block (block); cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL); + if (processing_template_decl) + block = build_stmt (input_location, EXPR_STMT, block); add_stmt (block); if (ctor) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b8a279f8b08b..1bd014696fcd 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4338,7 +4338,7 @@ expand_or_defer_fn_1 (tree fn) if (DECL_INTERFACE_KNOWN (fn)) /* We've already made a decision as to how this function will be handled. */; - else if (!at_eof) + else if (!at_eof || DECL_OMP_DECLARE_REDUCTION_P (fn)) tentative_decl_linkage (fn); else import_export_decl (fn); @@ -4349,6 +4349,7 @@ expand_or_defer_fn_1 (tree fn) be emitted; there may be callers in other DLLs. */ if (DECL_DECLARED_INLINE_P (fn) && !DECL_REALLY_EXTERN (fn) + && !DECL_OMP_DECLARE_REDUCTION_P (fn) && (flag_keep_inline_functions || (flag_keep_inline_dllexport && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn))))) @@ -4381,6 +4382,9 @@ expand_or_defer_fn_1 (tree fn) return false; } + if (DECL_OMP_DECLARE_REDUCTION_P (fn)) + return false; + return true; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eb6108b3a3ed..917de8fb18ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,12 @@ 2019-12-20 Jakub Jelinek Backported from mainline + 2019-11-29 Jakub Jelinek + + PR c++/60228 + * g++.dg/gomp/openmp-simd-2.C: Don't expect bodies for + DECL_OMP_DECLARE_REDUCTION_P functions. + 2019-11-28 Jakub Jelinek PR c++/92695 diff --git a/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C b/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C index e31c1ebecf9f..e66806845b7d 100644 --- a/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C +++ b/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C @@ -36,8 +36,6 @@ void bar(int n, float *a, float *b) a[i] = b[i]; } -/* { dg-final { scan-tree-dump-times "Function void omp declare reduction operator\\+" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "Function void omp declare reduction foo" 2 "original" } } */ /* { dg-final { scan-tree-dump-times "pragma omp simd reduction\\(u\\) reduction\\(t\\) reduction\\(\\+:s\\) aligned\\(a:32\\)" 1 "original" } } */ /* { dg-final { scan-tree-dump-times "pragma omp simd safelen\\(64\\)" 1 "original" } } */ /* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */ diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index c1959a44b8c6..ec959f302ca3 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,12 @@ +2019-12-20 Jakub Jelinek + + Backported from mainline + 2019-11-29 Jakub Jelinek + + PR c++/60228 + * testsuite/libgomp.c++/udr-20.C: New test. + * testsuite/libgomp.c++/udr-21.C: New test. + 2019-12-11 Thomas Schwinge Julian Brown diff --git a/libgomp/testsuite/libgomp.c++/udr-20.C b/libgomp/testsuite/libgomp.c++/udr-20.C new file mode 100644 index 000000000000..83388758edd9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/udr-20.C @@ -0,0 +1,54 @@ +// PR c++/60228 +// { dg-additional-options "-std=c++11" } + +extern "C" void abort (); + +struct A +{ + typedef int T; + #pragma omp declare reduction (x : T : omp_out += omp_in + [](){ return 0; }()) initializer (omp_priv = [](){ return 0; }()) + static void foo (); +}; + +template +struct B +{ + #pragma omp declare reduction (x : T : omp_out += omp_in + [](){ return T (0); }()) initializer (omp_priv = [](){ return T (0); }()) + static void foo (); +}; + +void +A::foo () +{ + int r = 0, s = 0; + #pragma omp parallel for reduction (x : r, s) + for (int i = 0; i < 64; i++) + { + r++; + s += i; + } + if (r != 64 || s != (64 * 63) / 2) + abort (); +} + +template +void +B::foo () +{ + T r = 0, s = 0; + #pragma omp parallel for reduction (x : r, s) + for (int i = 0; i < 64; i++) + { + r++; + s += i; + } + if (r != 64 || s != (64 * 63) / 2) + abort (); +} + +int +main () +{ + A::foo (); + B::foo (); +} diff --git a/libgomp/testsuite/libgomp.c++/udr-21.C b/libgomp/testsuite/libgomp.c++/udr-21.C new file mode 100644 index 000000000000..9ec655718fda --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/udr-21.C @@ -0,0 +1,54 @@ +// PR c++/60228 +// { dg-additional-options "-std=c++11" } + +extern "C" void abort (); + +struct A +{ + typedef int T; + #pragma omp declare reduction (y : T : [&omp_out, &omp_in]() { omp_out += omp_in; return 0; }()) initializer (omp_priv = [omp_orig]() { return omp_orig; }()) + static void foo (); +}; + +template +struct B +{ + #pragma omp declare reduction (y : T : [&omp_out, &omp_in]() { omp_out += omp_in; return 0; }()) initializer (omp_priv = [omp_orig]() { return omp_orig; }()) + static void foo (); +}; + +void +A::foo () +{ + int r = 0, s = 0; + #pragma omp parallel for reduction (y : r, s) + for (int i = 0; i < 64; i++) + { + r++; + s += i; + } + if (r != 64 || s != (64 * 63) / 2) + abort (); +} + +template +void +B::foo () +{ + T r = 0, s = 0; + #pragma omp parallel for reduction (y : r, s) + for (int i = 0; i < 64; i++) + { + r++; + s += i; + } + if (r != 64 || s != (64 * 63) / 2) + abort (); +} + +int +main () +{ + A::foo (); + B::foo (); +} -- 2.47.2