Hi! When parsing lambdas, the C++ FE emits DECL_EXPRs with TYPE_DECLs for the lambda structs, which confuse the OpenMP iterator init handling.
Fixed by moving those over into the for block. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2016-08-08 Jakub Jelinek <ja...@redhat.com> 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. --- gcc/cp/parser.c.jj 2016-08-06 12:11:45.000000000 +0200 +++ gcc/cp/parser.c 2016-08-08 18:12:06.335194885 +0200 @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. #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 * 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 *parse } 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; --- libgomp/testsuite/libgomp.c++/pr58706.C.jj 2016-08-08 18:41:08.129276653 +0200 +++ libgomp/testsuite/libgomp.c++/pr58706.C 2016-08-08 18:47:44.014521578 +0200 @@ -0,0 +1,47 @@ +// PR c++/58706 +// { dg-do run } +// { dg-options "-std=c++11" } + +template <typename T> +T +foo () +{ + T n = T (); +#pragma omp parallel for reduction (+: n) + for (T i = [](){ return 3; }(); i < 10; ++i) + n++; + return n; +} + +template <typename T> +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 <typename T> +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 <int> () != 7 || foo <long long> () != 7) + __builtin_abort (); + if (bar <int> () != 5 || bar <char> () != 5) + __builtin_abort (); + if (baz <int> () != 9 || baz <long long> () != 9) + __builtin_abort (); +} Jakub