https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100472
Bug ID: 100472 Summary: [C++17] Wrong template non-type argument handling on function reference to noexcept functions Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: template<void(&)()> void h() {} void f() noexcept {} int main() { h<f>(); } g++ prog.cc -Wall -Wextra -std=c++17 prog.cc: In function 'int main()': prog.cc:10:7: error: no matching function for call to 'h<f>()' 10 | h<f>(); | ^ prog.cc:2:6: note: candidate: 'template<void (& <anonymous>)()> void h()' 2 | void h() | ^ prog.cc:2:6: note: template argument deduction/substitution failed: prog.cc:10:7: error: '(void (&)())f' is not a valid template argument for type 'void (&)()' 10 | h<f>(); | ^ prog.cc:10:7: note: it must be the name of a function with external linkage Removing `noexcept` makes all errors disappeared. So, the real failure is from the initialization of the template non-type parameter. This should not fail as per the rules in [temp.arg.nontype], [dcl.init.ref] and [expr.const] (see also N4268). Even if the conversion should have been failed, the last diagnostic message is clearly wrong and confusing. This message comes from the conversion performed on the template non-type argument as I see in convert_nontype_argument_function in pt.c, and it should not occur since the [temp.arg.nontype] changes in C++11.