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

            Bug ID: 115620
           Summary: internal compiler error: output_operand: invalid
                    expression as operand
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: iamanonymous.cs at gmail dot com
  Target Milestone: ---
            Target: x86_64

*******************************************************************************
The compiler produces an internal error during tsubst_pack_expansion when
compiling the provided code with the specified options. 
The issue can also be reproduced on Compiler Explorer.

*******************************************************************************
OS and Platform:
# uname -a
Linux ubuntu 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023
x86_64 x86_64 x86_64 GNU/Linux
*******************************************************************************
# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/root/gdbtest/gcc/gcc-15/libexec/gcc/x86_64-pc-linux-gnu/15.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /root/gdbtest/gcc/obj/../gcc/configure
--prefix=/root/gdbtest/gcc/gcc-15 --enable-languages=c,c++,fortran,go
--disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.0.0 20240509 (experimental) (GCC) 
*******************************************************************************
Program:
# cat code_0.cpp

#include <concepts>
#include <type_traits>
#include <utility>

[[maybe_unused]] constexpr inline static auto lpartial =
    [](auto fn, auto... t0) constexpr noexcept {
      return [=](auto... rest) constexpr noexcept
        requires requires { fn(t0..., rest...); }
      { return fn(t0..., rest...); };
    };

[[maybe_unused]] constexpr inline static auto fix =
    [](auto self) constexpr noexcept {
      return [=](auto... args) constexpr noexcept
        requires requires { self(self, args...); }
      { return self(self, args...); };
    };

[[maybe_unused]] constexpr inline static auto currify0 =
    [](auto self, auto v, auto fn) constexpr noexcept {
      return [=](auto... as) constexpr noexcept
        requires(
            (v.value > sizeof...(as) && requires { lpartial(fn, as...); }) ||
            (v.value == sizeof...(as) && requires { fn(as...); }))
      {
        if constexpr (v.value > sizeof...(as))
          return self(self, std::integral_constant<std::size_t, v.value -
sizeof...(as)>{}, lpartial(fn, as...));
        else
          return fn(as...);
      };
    };

[[maybe_unused]] constexpr static inline auto plus =
    [](auto x, auto y) constexpr noexcept
  requires requires { x + y; }
{ return x + y; };

#undef lambda_body

[[maybe_unused]] constexpr static inline auto plus_ =
    fix(currify0)(std::integral_constant<std::size_t, 2>{}, plus);




*******************************************************************************
Command Lines:
# g++ code_0.cpp -O3 -Wpedantic -Wall -Wextra -Wconversion -Wshadow
-Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual
-Wpedantic -Wsign-conversion -Wmisleading-indentation -Wduplicated-cond
-Wnull-dereference -Wdouble-promotion -Wformat=2 -Wno-unused-parameter -c -o
code_0.o
code_0.cpp:8:9: warning: identifier ‘requires’ is a keyword in C++20
[-Wc++20-compat]
    8 |         requires requires { fn(t0..., rest...); }
      |         ^~~~~~~~
code_0.cpp: In lambda function:
code_0.cpp:8:9: error: ‘requires’ only available with ‘-std=c++20’ or
‘-fconcepts’
code_0.cpp:8:18: error: ‘requires’ was not declared in this scope
    8 |         requires requires { fn(t0..., rest...); }
      |                  ^~~~~~~~
code_0.cpp:8:50: error: expected ‘;’ before ‘{’ token
    8 |         requires requires { fn(t0..., rest...); }
      |                                                  ^
      |                                                  ;
    9 |       { return fn(t0..., rest...); };
      |       ~                                           
code_0.cpp:9:26: error: ‘rest’ was not declared in this scope
    9 |       { return fn(t0..., rest...); };
      |                          ^~~~
code_0.cpp: In lambda function:
code_0.cpp:15:9: error: ‘requires’ only available with ‘-std=c++20’ or
‘-fconcepts’
   15 |         requires requires { self(self, args...); }
      |         ^~~~~~~~
code_0.cpp:15:18: error: ‘requires’ was not declared in this scope
   15 |         requires requires { self(self, args...); }
      |                  ^~~~~~~~
code_0.cpp:15:51: error: expected ‘;’ before ‘{’ token
   15 |         requires requires { self(self, args...); }
      |                                                   ^
      |                                                   ;
   16 |       { return self(self, args...); };
      |       ~                                            
code_0.cpp:16:27: error: ‘args’ was not declared in this scope
   16 |       { return self(self, args...); };
      |                           ^~~~
code_0.cpp: In lambda function:
code_0.cpp:22:9: error: ‘requires’ only available with ‘-std=c++20’ or
‘-fconcepts’
   22 |         requires(
      |         ^~~~~~~~
code_0.cpp:23:41: error: ‘requires’ was not declared in this scope
   23 |             (v.value > sizeof...(as) && requires { lpartial(fn, as...);
}) ||
      |                                         ^~~~~~~~
code_0.cpp:23:49: error: expected ‘)’ before ‘{’ token
   23 |             (v.value > sizeof...(as) && requires { lpartial(fn, as...);
}) ||
      |             ~                                   ^~
      |                                                 )
code_0.cpp:24:35: error: ‘as’ has not been declared
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |                                   ^~
code_0.cpp:24:42: error: ‘requires’ was not declared in this scope
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |                                          ^~~~~~~~
code_0.cpp:24:50: error: expected ‘)’ before ‘{’ token
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |             ~                                    ^~
      |                                                  )
code_0.cpp: In lambda function:
code_0.cpp:24:65: error: expected ‘{’ before ‘)’ token
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |                                                                 ^
code_0.cpp: In lambda function:
code_0.cpp:24:65: error: expected ‘;’ before ‘)’ token
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |                                                                 ^
      |                                                                 ;
code_0.cpp:24:65: error: expected primary-expression before ‘)’ token
code_0.cpp: At global scope:
code_0.cpp:35:3: error: ‘requires’ only available with ‘-std=c++20’ or
‘-fconcepts’
   35 |   requires requires { x + y; }
      |   ^~~~~~~~
code_0.cpp:35:12: error: ‘requires’ was not declared in this scope
   35 |   requires requires { x + y; }
      |            ^~~~~~~~
code_0.cpp:36:1: error: expected ‘,’ or ‘;’ before ‘{’ token
   36 | { return x + y; };
      | ^
code_0.cpp: In instantiation of ‘<lambda(auto:6, auto:7, auto:8)> [with auto:6
= <lambda(auto:6, auto:7, auto:8)>; auto:7 = std::integral_constant<long
unsigned int, 2>; auto:8 = <lambda(auto:10, auto:11)>]’:
code_0.cpp:15:33:   required from ‘<lambda(auto:4)>::<lambda(auto:5 ...)> [with
auto:5 = {std::integral_constant<long unsigned int, 2>, <lambda(auto:10,
auto:11)>}]’
   15 |         requires requires { self(self, args...); }
      |                             ~~~~^~~~~~~~~~~~~~~
code_0.cpp:41:18:   required from here
   41 |     fix(currify0)(std::integral_constant<std::size_t, 2>{}, plus);
      |     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
code_0.cpp:21:14: internal compiler error: in tsubst_pack_expansion, at
cp/pt.cc:13703
   21 |       return [=](auto... as) constexpr noexcept
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   22 |         requires(
      |         ~~~~~~~~~
   23 |             (v.value > sizeof...(as) && requires { lpartial(fn, as...);
}) ||
      |            
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   24 |             (v.value == sizeof...(as) && requires { fn(as...); }))
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x835ed1 tsubst_pack_expansion(tree_node*, tree_node*, int, tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:13703
0xcd62af tsubst_arg_types
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:15732
0xcd6821 tsubst_arg_types
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:15724
0xcd6821 tsubst_function_type
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:15901
0xcd29bb tsubst(tree_node*, tree_node*, int, tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:16725
0xce18ce tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:19760
0xcbe1a0 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:21757
0xcc4837 tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:19482
0xcc6446 tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18434
0xcc6106 tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18410
0xcc6106 tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18424
0xcc6bee tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18797
0xcc6bee tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18797
0xce0b52 tsubst_stmt
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:18410
0xce0b52 instantiate_body
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:27107
0xcc4425 instantiate_decl(tree_node*, bool, bool)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/pt.cc:27392
0xb87e57 maybe_instantiate_decl(tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/decl2.cc:5693
0xb87e57 maybe_instantiate_decl(tree_node*)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/decl2.cc:5680
0xb89910 mark_used(tree_node*, int)
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/decl2.cc:6001
0xab9beb build_over_call
        /root/gdbtest/gcc/obj/../gcc/gcc/cp/call.cc:10581
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.


*******************************************************************************

Also ICE on trunk, compiler explorer:https://godbolt.org/z/K651cs6qh

*******************************************************************************

Reply via email to