Bug 105839 - internal compiler error: in tsubst_omp_for_iterator with openmp and structured bindings in a template
Summary: internal compiler error: in tsubst_omp_for_iterator with openmp and structure...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, openmp
Depends on:
Blocks:
 
Reported: 2022-06-03 16:49 UTC by northon_patrick3
Modified: 2024-04-13 20:45 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Result from -freport-bug (1.21 KB, text/x-csrc)
2022-06-03 16:49 UTC, northon_patrick3
Details
gcc13-pr105839.patch (1.04 KB, patch)
2023-03-01 11:47 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description northon_patrick3 2022-06-03 16:49:34 UTC
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`.
Comment 1 Jakub Jelinek 2022-06-03 17:07:15 UTC
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);
}
Comment 2 Jakub Jelinek 2023-03-01 11:10:57 UTC
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).
Comment 3 Jakub Jelinek 2023-03-01 11:47:02 UTC
Created attachment 54564 [details]
gcc13-pr105839.patch

Untested fix for the error recovery issue.
Comment 4 northon_patrick3 2023-03-01 11:52:37 UTC
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);
}
```
Comment 5 Jakub Jelinek 2023-03-01 12:01:26 UTC
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.
Comment 6 GCC Commits 2023-03-02 08:07:09 UTC
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.