https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90799
Bug ID: 90799
Summary: noexcept specification dependent on template argument
throws internal compiler error when trying to deduce
it from a function argument
Product: gcc
Version: 9.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: franwade33 at googlemail dot com
Target Milestone: ---
If you have a non-type template argument `bool is_noexcept` that is deduced
from `noexcept(is_noexcept)` on a function pointer / member function pointer,
it gives an internal compiler error if the function was instantiated from a
template and the noexcept specifier is dependent on a template parameter.
For example, the following compiled with or without `-DMEMBER` both give the
same output:
template<class T>
void foo() noexcept(T::value);
struct S {
static constexpr const bool value = true;
template<class T>
void bar() noexcept(T::value);
};
template<class... Args, bool is_noexcept>
constexpr bool is_noexcept_function(void(Args...) noexcept(is_noexcept))
noexcept {
return is_noexcept;
}
template<class... Args, bool is_noexcept>
constexpr bool is_noexcept_member_function(void(S::*)(Args...)
noexcept(is_noexcept)) noexcept {
return is_noexcept;
}
#ifdef MEMBER
static_assert(is_noexcept_member_function(&S::bar<S>));
#else
static_assert(is_noexcept_function(foo<S>));
#endif
Expected behaviour:
Nothing happens (static_assert is successful, as `is_noexcept` is deduced to be
true) in both cases.
Actual behaviour:
(Error with `g++ -std=c++17`)
test.cpp: In substitution of 'template<class ... Args, bool is_noexcept>
constexpr bool is_noexcept_function(void (*)(Args ...) noexcept (is_noexcept))
[with Args = <missing>; bool is_noexcept = <missing>]':
test.cpp:24:42: required from here
test.cpp:24:42: internal compiler error: in structural_comptypes, at
cp/typeck.c:1236
24 | static_assert(is_noexcept_function(foo<S>));
| ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
(Error with `g++ -std=c++17 -DMEMBER`)
test.cpp: In substitution of 'template<class ... Args, bool is_noexcept>
constexpr bool is_noexcept_member_function(void (S::*)(Args ...) noexcept
(is_noexcept)) [with Args = <missing>; bool is_noexcept = <missing>]':
test.cpp:22:53: required from here
test.cpp:22:53: internal compiler error: in structural_comptypes, at
cp/typeck.c:1236
22 | static_assert(is_noexcept_member_function(&S::bar<S>));
| ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
There also seems to be a problem deducing argument types, as if I replace
`template<class... Args, bool is_noexcept>` and `void(Args...)
noexcept(is_noexcept)` with just `template<bool is_noexcept>` and `void()
noexcept(is_noexcept)`, I don't get an internal compiler error but I get a
substitution failure:
error: no matching function for call to
'is_noexcept_(member_)function(<unresolved overloaded function type>)'
note: candidate: 'template<bool is_noexcept> ...'
note: template argument deduction/substitution failed:
note: couldn't deduce template parameter 'is_noexcept'
This is also the error I get in g++-8 (8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04)) in
all 4 cases (So no internal compiler error in g++-8).