From: Jakub Jelinek Date: Mon, 8 Aug 2016 19:50:29 +0000 (+0200) Subject: re PR c++/58706 (ICE with lambda in OpenMP for-loop) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5c9343960762bda86bc64dc19862dcf3088102cd;p=gcc.git re PR c++/58706 (ICE with lambda in OpenMP for-loop) PR c++/58706 * parser.c: Include tree-iterator.h. (cp_parser_omp_for_loop_init): Move lambda DECL_EXPRs from init to FOR_BLOCK. (cp_parser_omp_for_loop): Handle non-STATEMENT_LIST FOR_BLOCK entries. * testsuite/libgomp.c++/pr58706.C: New test. From-SVN: r239251 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4efbc7b153f..bd036a8a628 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,9 +1,18 @@ +2016-08-08 Jakub Jelinek + + PR c++/58706 + * parser.c: Include tree-iterator.h. + (cp_parser_omp_for_loop_init): Move lambda DECL_EXPRs from init + to FOR_BLOCK. + (cp_parser_omp_for_loop): Handle non-STATEMENT_LIST FOR_BLOCK + entries. + 2016-08-06 Jonathan Wakely * call.c (convert_like_real): Harmonize diagnostics for invalid reference binding. -2016-08-05 Martin Sebor +2016-08-05 Martin Sebor * constexpr.c (cxx_eval_store_expression): Remove hyphen from the spelling of "constant-expression" in diagnostic messages diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 72a494dae9e..cff735ba659 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "context.h" #include "cp-cilkplus.h" #include "gcc-rich-location.h" +#include "tree-iterator.h" /* The lexer. */ @@ -33495,7 +33496,33 @@ cp_parser_omp_for_loop_init (cp_parser *parser, init = NULL_TREE; } else - init = pop_stmt_list (this_pre_body); + { + init = pop_stmt_list (this_pre_body); + if (init && TREE_CODE (init) == STATEMENT_LIST) + { + tree_stmt_iterator i = tsi_start (init); + /* Move lambda DECL_EXPRs to FOR_BLOCK. */ + while (!tsi_end_p (i)) + { + tree t = tsi_stmt (i); + if (TREE_CODE (t) == DECL_EXPR + && TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL) + { + tsi_delink (&i); + vec_safe_push (for_block, t); + continue; + } + break; + } + if (tsi_one_before_end_p (i)) + { + tree t = tsi_stmt (i); + tsi_delink (&i); + free_stmt_list (init); + init = t; + } + } + } this_pre_body = NULL_TREE; } else @@ -33899,7 +33926,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, } while (!for_block->is_empty ()) - add_stmt (pop_stmt_list (for_block->pop ())); + { + tree t = for_block->pop (); + if (TREE_CODE (t) == STATEMENT_LIST) + add_stmt (pop_stmt_list (t)); + else + add_stmt (t); + } release_tree_vector (for_block); return ret; diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 70e765ef33a..ae5f28ffcc6 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2016-08-08 Jakub Jelinek + + PR c++/58706 + * testsuite/libgomp.c++/pr58706.C: New test. + 2016-08-04 Thomas Schwinge * testsuite/libgomp.oacc-c++/routine-1-auto.C: New file. diff --git a/libgomp/testsuite/libgomp.c++/pr58706.C b/libgomp/testsuite/libgomp.c++/pr58706.C new file mode 100644 index 00000000000..3d8ea89ceb4 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr58706.C @@ -0,0 +1,47 @@ +// PR c++/58706 +// { dg-do run } +// { dg-options "-std=c++11" } + +template +T +foo () +{ + T n = T (); +#pragma omp parallel for reduction (+: n) + for (T i = [](){ return 3; }(); i < 10; ++i) + n++; + return n; +} + +template +T +bar () +{ + T n = T (); +#pragma omp parallel for reduction (+: n) + for (T i = [](){ return 1; }() + [](){ return 4; }(); i < 10; ++i) + n++; + return n; +} + +template +T +baz () +{ + T n = T (); +#pragma omp parallel for reduction (+: n) + for (T i = T (); i < [](){ return 7; }() + [](){ return 11; }(); i += [](){ return 3; }() - [](){ return 1; }()) + n++; + return n; +} + +int +main () +{ + if (foo () != 7 || foo () != 7) + __builtin_abort (); + if (bar () != 5 || bar () != 5) + __builtin_abort (); + if (baz () != 9 || baz () != 9) + __builtin_abort (); +}