aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2016-08-08 21:50:29 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-08-08 21:50:29 +0200
commit5c9343960762bda86bc64dc19862dcf3088102cd (patch)
tree3f56e326fdf2a763aae6e017857aec98eedbd43d /gcc/cp/parser.c
parent77524e0d975d91248c2178a7d607cc6a19209cb6 (diff)
downloadgcc-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.c37
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;