https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105143
Bug ID: 105143 Summary: ICE when trying to emit a [[nodiscard]] warning Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: rl.alt.accnt at gmail dot com Target Milestone: --- I'm getting an internal compiler error when I try to compile the code below: ``` #include <algorithm> #include <type_traits> #include <string> template <size_t sz> struct str_lit { char data[sz]{}; constexpr str_lit(const char (&_data)[sz]) { std::copy_n(_data, sz, data); } template <typename str> constexpr bool operator==(const str& s) const { return sizeof data == sizeof s.data && __builtin_strcmp(data, s.data) == 0; } }; template <str_lit _name, typename _type = std::string> struct option { using type = _type; static constexpr inline decltype(_name) name = _name; }; template <typename... opts> struct command_line_options { template <str_lit s, typename... options> struct type_of; template <str_lit s, typename option, typename option2> struct type_of<s, option, option2> { using type = std::conditional_t<s == option::name, typename option::type, typename option2::type>; }; template <str_lit s, typename option, typename... options> struct type_of<s, option, options...> { using type = std::conditional_t<sizeof...(options) == 0 || s == option::name, typename option::type, typename type_of<s, options...>::type>; }; template <str_lit s> using type_of_t = typename type_of<s, opts...>::type; struct parsed_options { template <str_lit s> [[nodiscard]] type_of_t<s> get() { return {}; } }; }; using options = command_line_options< option<"--filename">, option<"--size", int64_t>>; int main() { options::parsed_options opts; opts.get<"--filename">(); // (void) opts.get<"--filename">(); // Doing this instead works } ``` It seems that this happens while it is trying to emit a warning about the unused return value of `opts.get<"--filename">()` since when I do use it or cast it to (void) it compiles just fine. The same problem also occurs with `[[gnu::warn_unused_result]]` instead of `[[nodiscard]]`. Here's the backtrace: ``` ' Internal compiler error: Error reporting routines re-entered. 0xf3d164 warning(int, char const*, ...) ???:0 0x1190cb1 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0x1479e26 pp_format(pretty_printer*, text_info*) ???:0 0xf3d5cf diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*) ???:0 0xf953af warning_at(unsigned int, int, char const*, ...) ???:0 0x10fa93c convert_to_void(tree_node*, impl_conv_void, int) ???:0 0x10f9d03 finish_expr_stmt(tree_node*) ???:0 0x14e7873 c_parse_file() ???:0 0x14c9d9e c_common_parse_file() ???:0 ``` I'm running gcc 11.2.0 on x86_64 Arch Linux, but I've also tested this with several versions of GCC on compiler explorer including trunk and I ran into much the same problem. Here's a link to that: https://godbolt.org/z/qPY4ccPfr.