We currently ICE when emitting the error message for this invalid code: === cut here === struct foo { template<int> void not_const() {} }; void fn(const foo& obj) { obj.not_const<5>(); } === cut here ===
The problem is that get_fndecl_argument_location assumes that it has a FUNCTION_DECL in its hands to find the location of the bad argument. It might however have a TEMPLATE_DECL if there's a single candidate that cannot be instantiated, like here. This patch simply defaults to using the FNDECL's location in this case, which fixes this PR. Successfully tested on x86_64-pc-linux-gnu. PR c++/115364 gcc/cp/ChangeLog: * call.cc (get_fndecl_argument_location): Use FNDECL's location for TEMPLATE_DECLs. gcc/testsuite/ChangeLog: * g++.dg/overload/template7.C: New test. --- gcc/cp/call.cc | 4 ++++ gcc/testsuite/g++.dg/overload/template7.C | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 gcc/testsuite/g++.dg/overload/template7.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 7bbc1fb0c78..d5ff2311e63 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -8347,6 +8347,10 @@ get_fndecl_argument_location (tree fndecl, int argnum) if (DECL_ARTIFICIAL (fndecl)) return DECL_SOURCE_LOCATION (fndecl); + /* Use FNDECL's location for TEMPLATE_DECLs. */ + if (TREE_CODE (fndecl) == TEMPLATE_DECL) + return DECL_SOURCE_LOCATION (fndecl); + int i; tree param; diff --git a/gcc/testsuite/g++.dg/overload/template7.C b/gcc/testsuite/g++.dg/overload/template7.C new file mode 100644 index 00000000000..67191c4ff62 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/template7.C @@ -0,0 +1,9 @@ +// PR c++/115364 +// { dg-do compile } + +struct foo { + template<int> void not_const() {} // { dg-note "initializing" } +}; +void fn(const foo& obj) { + obj.not_const<5>(); // { dg-error "cannot convert" } +} -- 2.44.0