diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-08-08 21:50:29 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-08-08 21:50:29 +0200 |
commit | 5c9343960762bda86bc64dc19862dcf3088102cd (patch) | |
tree | 3f56e326fdf2a763aae6e017857aec98eedbd43d /gcc/cp/parser.c | |
parent | 77524e0d975d91248c2178a7d607cc6a19209cb6 (diff) | |
download | gcc-5c9343960762bda86bc64dc19862dcf3088102cd.zip gcc-5c9343960762bda86bc64dc19862dcf3088102cd.tar.gz gcc-5c9343960762bda86bc64dc19862dcf3088102cd.tar.bz2 |
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
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 72a494d..cff735b 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; |