On Sun, Jul 23, 2023 at 04:15:19PM -0600, Sandra Loosemore wrote: > OpenMP 5.0 removed the restriction that multiple collapsed loops must > be perfectly nested, allowing "intervening code" (including nested > BLOCKs) before or after each nested loop. In GCC this code is moved > into the inner loop body by the respective front ends. > > This patch changes the C++ front end to use recursive descent parsing > on nested loops within an "omp for" construct, rather than an > iterative approach, in order to preserve proper nesting of compound > statements. Preserving cleanups (destructors) for class objects > declared in intervening code and loop initializers complicates moving > the former into the body of the loop; this is handled by parsing the > entire construct before reassembling any of it. > > gcc/cp/ChangeLog > * cp-tree.h (cp_convert_omp_range_for): Adjust declaration. > * parser.cc (struct omp_for_parse_data): New. > (cp_parser_postfix_expression): Diagnose calls to OpenMP runtime > in intervening code. > (check_omp_intervening_code): New. > (cp_parser_statement_seq_opt): Special-case nested loops, blocks, > and other constructs for OpenMP loops. > (cp_parser_iteration_statement): Reject loops in intervening code. > (cp_parser_omp_for_loop_init): Expand comments and tweak the > interface slightly to better distinguish input/output parameters. > (cp_convert_omp_range_for): Likewise. > (cp_parser_omp_loop_nest): New, split from cp_parser_omp_for_loop > and largely rewritten. Add more comments. > (insert_structured_blocks): New. > (find_structured_blocks): New. > (struct sit_data, substitute_in_tree_walker, substitute_in_tree): > New. > (fixup_blocks_walker): New. > (cp_parser_omp_for_loop): Rewrite to use recursive descent instead > of a loop. Add logic to reshuffle the bits of code collected > during parsing so intervening code gets moved to the loop body. > (cp_parser_omp_loop): Remove call to finish_omp_for_block, which > is now redundant. > (cp_parser_omp_simd): Likewise. > (cp_parser_omp_for): Likewise. > (cp_parser_omp_distribute): Likewise. > (cp_parser_oacc_loop): Likewise. > (cp_parser_omp_taskloop): Likewise. > (cp_parser_pragma): Reject OpenMP pragmas in intervening code. > * parser.h (struct cp_parser): Add omp_for_parse_state field. > * pt.cc (tsubst_omp_for_iterator): Adjust call to > cp_convert_omp_range_for. > * semantics.cc (finish_omp_for): Try harder to preserve location > of loop variable init expression for use in diagnostics. > (struct fofb_data, finish_omp_for_block_walker): New. > (finish_omp_for_block): Allow variables to be bound in a BIND_EXPR > nested inside BIND instead of directly in BIND itself. > > gcc/testsuite/ChangeLog > * c-c++-common/goacc/tile-2.c: Adjust expected error patterns. > * g++.dg/gomp/attrs-imperfect1.C: New test. > * g++.dg/gomp/attrs-imperfect2.C: New test. > * g++.dg/gomp/attrs-imperfect3.C: New test. > * g++.dg/gomp/attrs-imperfect4.C: New test. > * g++.dg/gomp/attrs-imperfect5.C: New test. > * g++.dg/gomp/pr41967.C: Adjust expected error patterns. > * g++.dg/gomp/tpl-imperfect-gotos.C: New test. > * g++.dg/gomp/tpl-imperfect-invalid-scope.C: New test. > > libgomp/ChangeLog > * testsuite/libgomp.c++/attrs-imperfect1.C: New test. > * testsuite/libgomp.c++/attrs-imperfect2.C: New test. > * testsuite/libgomp.c++/attrs-imperfect3.C: New test. > * testsuite/libgomp.c++/attrs-imperfect4.C: New test. > * testsuite/libgomp.c++/attrs-imperfect5.C: New test. > * testsuite/libgomp.c++/attrs-imperfect6.C: New test. > * testsuite/libgomp.c++/imperfect-class-1.C: New test. > * testsuite/libgomp.c++/imperfect-class-2.C: New test. > * testsuite/libgomp.c++/imperfect-class-3.C: New test. > * testsuite/libgomp.c++/imperfect-destructor.C: New test. > * testsuite/libgomp.c++/imperfect-template-1.C: New test. > * testsuite/libgomp.c++/imperfect-template-2.C: New test. > * testsuite/libgomp.c++/imperfect-template-3.C: New test.
Ok (though, if the c-c++-common tests are tweaked in the C patch, this patch needs to undo that). Jakub