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.