https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85214

            Bug ID: 85214
           Summary: ICE on valid C++17 code on x86_64-linux-gnu: in
                    tsubst_copy, at cp/pt.c:14562
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

Created attachment 43846
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43846&action=edit
preprocessed *.i* file

Below code leads to an ICE with gcc 7.3 and previous 7.x versions. It compiles
fine with clang 6.0.0 and clang 5.0.0.

Note that I've translated below console output to english manually since I'm
on a different locale.

-------------------------------------------------------------------------------

$ g++ -v
Using built-in specs.
COLLECT_GCC=./g++
COLLECT_LTO_WRAPPER=/usr/local/gcc-7.3.0/libexec/gcc/x86_64-pc-linux-gnu/7.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-7.3.0/configure --prefix /usr/local/gcc-7.3.0
Thread modell: posix
gcc version 7.3.0 (GCC)


$ g++ -c -std=c++17 gcc_bug.cpp
gcc_bug.cpp: In instantiation of »main()::<lambda(auto:1)>::<lambda(auto:2)>
[with auto:2 = std::integral_constant<long unsigned int, 0>; auto:1 =
std::integral_constant<long unsigned int, 0>]«:
gcc_bug.cpp:8:51:   required by »constexpr void static_for(F&&,
std::index_sequence<s ...>) [with F = main()::<lambda(auto:1)> [mit auto:1 =
std::integral_constant<long unsigned int, 0>]::<lambda(auto:2)>; long unsigned
int ...s = {0, 1, 2, 3}; std::index_sequence<s ...> =
std::integer_sequence<long unsigned int, 0, 1, 2, 3>]«
gcc_bug.cpp:14:15:   required by »constexpr void static_for(F&&) [with long
unsigned int iterations = 4; F = main()::<lambda(auto:1)> [mit auto:1 =
std::integral_constant<long unsigned int, 0>]::<lambda(auto:2)>]«
gcc_bug.cpp:26:37:   required by »constexpr void static_for(F&&,
std::index_sequence<s ...>) [with F = main()::<lambda(auto:1)>; long unsigned
int ...s = {0, 1, 2, 3}; std::index_sequence<s ...> =
std::integer_sequence<long unsigned int, 0, 1, 2, 3>]«
gcc_bug.cpp:14:15:   required by »constexpr void static_for(F&&) [with long
unsigned int iterations = 4; F = main()::<lambda(auto:1)>]«
gcc_bug.cpp:32:6:   required from here
gcc_bug.cpp:29:27: internal compiler error: in tsubst_copy, at cp/pt.c:14562
             if constexpr (std::is_same_v<first_t, second_t>)
                           ^~~
0x616be7 tsubst_copy
        ../../gcc-7.3.0/gcc/cp/pt.c:14562
0x61e5ee tsubst_copy
        ../../gcc-7.3.0/gcc/cp/pt.c:14538
0x61e5ee tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:17861
0x6143a7 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16700
0x6143a7 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16581
0x627fc2 tsubst_template_args
        ../../gcc-7.3.0/gcc/cp/pt.c:11792
0x6288cc tsubst_aggr_type
        ../../gcc-7.3.0/gcc/cp/pt.c:11994
0x616fb6 tsubst(tree_node*, tree_node*, int, tree_node*)
        ../../gcc-7.3.0/gcc/cp/pt.c:14054
0x627fc2 tsubst_template_args
        ../../gcc-7.3.0/gcc/cp/pt.c:11792
0x61da01 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16767
0x6143a7 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16700
0x6143a7 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16581
0x613ad5 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16019
0x614245 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:15828
0x6140db tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16058
0x614245 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:15828
0x6140db tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:16058
0x612235 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:15813
0x612235 instantiate_decl(tree_node*, bool, bool)
        ../../gcc-7.3.0/gcc/cp/pt.c:23021
0x64f173 maybe_instantiate_decl
        ../../gcc-7.3.0/gcc/cp/decl2.c:5021
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

-------------------------------------------------------------------------------

#include <cstddef>
#include <utility>
#include <tuple>

template<typename F, std::size_t... s>
constexpr void static_for(F&& function, std::index_sequence<s...>)
{
    [[maybe_unused]] int unpack[] = { 0,
(function(std::integral_constant<std::size_t, s>{}), 0)... };
}

template<std::size_t iterations, typename F>
constexpr void static_for(F&& function)
{
    static_for(std::forward<F>(function),
std::make_index_sequence<iterations>());
}

int main()
{
    using some_types = std::tuple<int, float, char, double>;
    constexpr const size_t some_types_count = std::tuple_size_v<some_types>;

    int count = 0;
    static_for<some_types_count>([&count](auto i)
    {
        using first_t = std::tuple_element_t<i, some_types>;
        static_for<some_types_count>([&count](auto j)
        {
            using second_t = std::tuple_element_t<j, some_types>;
            if constexpr (std::is_same_v<first_t, second_t>)
                ++count;
        });
    });

    return count;
}

Reply via email to