Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g++: deducing this in recursive lambdas fails to compile #22878

Open
2 of 6 tasks
cuellius opened this issue Dec 22, 2024 · 4 comments
Open
2 of 6 tasks

g++: deducing this in recursive lambdas fails to compile #22878

cuellius opened this issue Dec 22, 2024 · 4 comments

Comments

@cuellius
Copy link

Description / Steps to reproduce the issue

Consider the following code:

main.cpp -- deducing this version
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <functional>

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    for (int tt = 0; tt < t; tt++)
    {
        int n;
        long long x, y;

        std::cin >> n >> x >> y;

        std::vector<long long> a(n);
        for (int i = 0; i < n; i++) std::cin >> a[i];

        std::vector<long long> tree[(n + 7) << 2];

        auto tree_build = [&](this auto const &tree_build, int v, int tl, int tr) -> void
        {
            if (tl == tr)
                tree[v] = { a[tl] };
            else
            {
                int tm = (tl + tr) >> 1;
                tree_build(v << 1, tl, tm);
                tree_build((v << 1) | 1, tm + 1, tr);
                std::merge(tree[v << 1].begin(), tree[v << 1].end(),
                           tree[(v << 1) | 1].begin(), tree[(v << 1) | 1].end(),
                           std::back_inserter(tree[v]));
            }
        };

        //std::function<long long(int, int, int, int, int, long long, long long)> tree_query;
        auto tree_query = [&](this auto const &tree_query, int v, int tl, int tr, int l, int r, long long low, long long high) -> long long
        {
            if (l > r)
                return 0;
            if (l == tl && tr == r)
            {
                auto it_low = std::lower_bound(tree[v].begin(), tree[v].end(), low);
                auto it_high = std::upper_bound(tree[v].begin(), tree[v].end(), high);
                return std::distance(it_low, it_high);
            }

            int tm = (tl + tr) >> 1;
            return tree_query(v << 1, tl, tm, l, std::min(r, tm), low, high) +
                   tree_query((v << 1) | 1, tm + 1, tr, std::max(l,tm+1), r, low, high);
        };

        //tree_build(1, 0, n - 1);

        long long sum = std::accumulate(a.begin(), a.end(), 0ll), ans = 0;
        for (int i = 0; i < n - 1; i++)
        {
            //x <= sum - a[i] - a[j] <= y
            //x - sum + a[i] <= -a[j] <= y - sum + a[i]
            //sum - a[i] - y <= a[j] <= sum - a[i] - x
            ans += tree_query(1, 0, n - 1, i + 1, n - 1, sum - a[i] - y, sum - a[i] - x);
        }

        std::cout << ans << '\n';
    }

    return 0;
}

I compile it with g++ -O2 -std=c++23 main.cpp -o main, where main.cpp is a file with this code, and get the following message:

main.cpp: In lambda function:
main.cpp:31:17: internal compiler error: Segmentation fault
   31 |                 tree[v] = { a[tl] };
      |                 ^~~~
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://github.com/msys2/MINGW-packages/issues> for instructions.

Expected behavior

The code should be correctly compiled. It should behave something like the following code:

main.cpp -- std::function version
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <functional>

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    for (int tt = 0; tt < t; tt++)
    {
        int n;
        long long x, y;

        std::cin >> n >> x >> y;

        std::vector<long long> a(n);
        for (int i = 0; i < n; i++) std::cin >> a[i];

        std::vector<long long> tree[(n + 7) << 2];
        std::function<void(int, int, int)> tree_build;
        tree_build = [&](int v, int tl, int tr) -> void
        {
            if (tl == tr)
                tree[v] = { a[tl] };
            else
            {
                int tm = (tl + tr) >> 1;
                tree_build(v << 1, tl, tm);
                tree_build((v << 1) | 1, tm + 1, tr);
                std::merge(tree[v << 1].begin(), tree[v << 1].end(),
                           tree[(v << 1) | 1].begin(), tree[(v << 1) | 1].end(),
                           std::back_inserter(tree[v]));
            }
        };

        std::function<long long(int, int, int, int, int, long long, long long)> tree_query;
        tree_query = [&](int v, int tl, int tr, int l, int r, long long low, long long high) -> long long
        {
            if (l > r)
                return 0;
            if (l == tl && tr == r)
            {
                auto it_low = std::lower_bound(tree[v].begin(), tree[v].end(), low);
                auto it_high = std::upper_bound(tree[v].begin(), tree[v].end(), high);
                return std::distance(it_low, it_high);
            }

            int tm = (tl + tr) >> 1;
            return tree_query(v << 1, tl, tm, l, std::min(r, tm), low, high) +
                   tree_query((v << 1) | 1, tm + 1, tr, std::max(l,tm+1), r, low, high);
        };

        tree_build(1, 0, n - 1);

        long long sum = std::accumulate(a.begin(), a.end(), 0ll), ans = 0;
        for (int i = 0; i < n - 1; i++)
        {
            //x <= sum - a[i] - a[j] <= y
            //x - sum + a[i] <= -a[j] <= y - sum + a[i]
            //sum - a[i] - y <= a[j] <= sum - a[i] - x
            ans += tree_query(1, 0, n - 1, i + 1, n - 1, sum - a[i] - y, sum - a[i] - x);
        }

        std::cout << ans << '\n';
    }

    return 0;
}

std::function version successfully compiles.

Actual behavior

The code fails to compile.

The command g++ -std=c++23 -O2 -freport-bug main.cpp -o main gives:

main.cpp: In lambda function:
main.cpp:31:17: internal compiler error: Segmentation fault
   31 |                 tree[v] = { a[tl] };
      |                 ^~~~
Please submit a full bug report, with preprocessed source.
See <https://github.com/msys2/MINGW-packages/issues> for instructions.
g++: fatal error: cannot execute 'C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/cc1plus.exe': open temporary output file
compilation terminated.

But, I can manually execute C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/cc1plus.exe, so I submit report without -freport-bug output. It also asks for preprocessed source, so I attach it (zipped):
main.zip

Verification

Windows Version

MSYS_NT-10.0-22631

MINGW environments affected

  • MINGW64
  • MINGW32
  • UCRT64
  • CLANG64
  • CLANGARM64

Are you willing to submit a PR?

No response

@cuellius cuellius added the bug label Dec 22, 2024
@cuellius
Copy link
Author

I don't know, since I don't use Linux now.

@Biswa96
Copy link
Member

Biswa96 commented Dec 22, 2024

Congrats! The compilation fails in Linux too.

$ g++ -O2 -std=c++23 main.cpp -o main
main.cpp: In lambda function:
main.cpp:30:9: internal compiler error: Segmentation fault
   30 |         tree[v] = {a[tl]};
      |         ^~~~
0x21a922a internal_error(char const*, ...)
        ???:0
0x92c9b4 cp_type_quals(tree_node const*)
        ???:0
0x942bfd build_simple_component_ref(tree_node*, tree_node*)
        ???:0
0x7efffb add_capture(tree_node*, tree_node*, tree_node*, bool, bool, unsigned int*)
        ???:0
0x7f060b add_default_capture(tree_node*, tree_node*, tree_node*)
        ???:0
0x9cd270 c_common_parse_file()
        ???:0
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues> for instructions.

$ g++ --version
g++ (GCC) 14.2.1 20240910

@Biswa96 Biswa96 added the GCC label Dec 22, 2024
@Biswa96
Copy link
Member

Biswa96 commented Dec 22, 2024

Wait, clang++ also fails. I wonder if the code is valid C++ or something is conflicting with standard.

@mati865
Copy link
Collaborator

mati865 commented Dec 22, 2024

Regardless of code validity, the compiler should never ICE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants