Created attachment 53079 [details] Result from -freport-bug The code: ``` void test(const auto &b1) { const auto loopImpl = [&](auto&& fc) { #pragma omp parallel for for(auto&& [v1, v2] : b1); }; loopImpl([]{}); } void test2() { int a[10]; test(a); } ``` The command line: ``` g++ -fopenmp test.cpp ``` The error: ``` internal compiler error: in tsubst_omp_for_iterator, at cp/pt.cc:18126 11 | for(auto&& [v1, v2] : b1); | ^~~ 0x1ac4724 internal_error(char const*, ...) ???:0 0x663b55 fancy_abort(char const*, int, char const*) ???:0 0x81d054 tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*) ???:0 0x80614a tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) ???:0 0x7fedbe instantiate_decl(tree_node*, bool, bool) ???:0 0x81e704 instantiate_pending_templates(int) ???:0 0x7173d1 c_parse_final_cleanups() ???:0 ``` GCC is configured with: ``` configure --prefix=/opt/pat-gcc --libdir=/opt/pat-gcc/lib --libexecdir=/opt/pat-gcc/lib --enable-languages=c,c++,lto --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/opt/pat-gcc/include/dlang/gdc ``` It happens from version 10.1 to latest commit at this date. It no longer crash if: - I don't use structured bindings. - b1 isn't a template. - I remove `auto&& fc`.
Adjusted testcase, so that it is already valid C++17: template <typename T> void foo (const T &x) { [&] (auto&& y) { #pragma omp parallel for for (auto&& [v1, v2] : x) ; } ([]{}); } void bar () { int a[10]; foo (a); }
Actually, I don't see how it can be valid. x (or b1) is const int[10] & and structured binding on int is clearly invalid. The ICE got fixed in r13-4460-gee4f25999f6832a1c, except that since r13-5379-gd427407a199a0c276cb02 we ICE again with -fopenmp -std=c++11 (error recovery after emitting some errors).
Created attachment 54564 [details] gcc13-pr105839.patch Untested fix for the error recovery issue.
Actually is still crash even on valid code: ``` template <typename T> void foo (const T &x) { [&] (auto&& y) { #pragma omp parallel for for (auto&& [v1, v2] : x) ; } ([]{}); } struct A { int a, b; }; void bar () { A a[10]; foo (a); } ```
Not on the trunk. Note, the r13-4460, r13-4461, r13-5379 changes PR84469 changes weren't backported to older branches intentionally, it is quite risky and had multiple follow-ups.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:f0ef740d54f47ff614eb02e13e8f4cb11dfbb140 commit r13-6407-gf0ef740d54f47ff614eb02e13e8f4cb11dfbb140 Author: Jakub Jelinek <jakub@redhat.com> Date: Thu Mar 2 09:02:12 2023 +0100 openmp: Fix up error recovery for invalid structured bindings in OpenMP range for loops [PR105839] The PR108503 temporary DECL_HAS_VALUE_EXPR_P clearing code can ICE during recovery, because cp_finish_decomp when it detects errors and reports them clears DECL_HAS_VALUE_EXPR_P, clears DECL_VALUE_EXPR and sets TREE_TYPE of the structured binding vars to error_mark_node. The PR108503 code had an assertion that DECL_HAS_VALUE_EXPR_P is set so that it can clear it and restore later. The following patch allows DECL_HAS_VALUE_EXPR_P to be unset if type is error_mark_node and doesn't set it again in that case. 2023-03-02 Jakub Jelinek <jakub@redhat.com> PR c++/105839 * parser.cc (cp_convert_omp_range_for): Allow in assert decomp_first_name without DECL_HAS_VALUE_EXPR_P if it has error_mark_node type. (cp_finish_omp_range_for): Don't set DECL_HAS_VALUE_EXPR_P back on decls which have error_mark_node type. * g++.dg/gomp/pr105839-1.C: New test. * g++.dg/gomp/pr105839-2.C: New test.