Here we issued the "invalid use of non-static member function" error with UNKNOWN_LOCATION, which merely shows "cc1plus" and no file/line. We can greatly improve this situation with the below.
The patch is IMHO trivial (though it's user-provided) to go in even at this point. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-02-28 Marek Polacek <pola...@redhat.com> PR c++/89537 - missing location for error with non-static member fn. * call.c (resolve_args): Use EXPR_LOCATION. * typeck.c (build_class_member_access_expr): Use input_location. * g++.dg/diagnostic/member-fn-1.C: New test. diff --git gcc/cp/call.c gcc/cp/call.c index fb67d905acd..d9073d7c23d 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -4246,7 +4246,7 @@ resolve_args (vec<tree, va_gc> *args, tsubst_flags_t complain) error ("invalid use of void expression"); return NULL; } - else if (invalid_nonstatic_memfn_p (arg->exp.locus, arg, complain)) + else if (invalid_nonstatic_memfn_p (EXPR_LOCATION (arg), arg, complain)) return NULL; } return args; diff --git gcc/cp/typeck.c gcc/cp/typeck.c index 1db9333b5ff..1bf9ad88141 100644 --- gcc/cp/typeck.c +++ gcc/cp/typeck.c @@ -2562,7 +2562,8 @@ build_class_member_access_expr (cp_expr object, tree member, type = unknown_type_node; /* Note that we do not convert OBJECT to the BASELINK_BINFO base. That will happen when the function is called. */ - result = build3 (COMPONENT_REF, type, object, member, NULL_TREE); + result = build3_loc (input_location, COMPONENT_REF, type, object, member, + NULL_TREE); } else if (TREE_CODE (member) == CONST_DECL) { diff --git gcc/testsuite/g++.dg/diagnostic/member-fn-1.C gcc/testsuite/g++.dg/diagnostic/member-fn-1.C new file mode 100644 index 00000000000..6d965d464fb --- /dev/null +++ gcc/testsuite/g++.dg/diagnostic/member-fn-1.C @@ -0,0 +1,38 @@ +// PR c++/89537 +// { dg-do compile { target c++11 } } + +template <typename> class A {}; +template <typename, typename, typename, typename> class B; +class C { + using mapped_type = int; + +public: + template <typename _Compare> + C(B<mapped_type, _Compare, A<int>, A<int>> *p1, unsigned) + : keys(p1->keys), // { dg-error "18: invalid use of non-static member function" } + values(p1->values) {} // { dg-error "20: invalid use of non-static member function" } + A<int> keys; + A<int> values; +}; +class D { +public: + using key_compare = int; + template <typename _Alloc> D(key_compare, _Alloc); +}; +template <typename _Tp, typename, typename, typename = A<_Tp>> class B { + using _Impl = D; + _Impl _M_impl; + +public: + using key_compare = int; + using iterator = C; + template <typename _Alloc> B(key_compare p1, _Alloc p2) : _M_impl(p1, p2) {} + template <typename _Alloc> B(_Alloc p1) : B(key_compare(), p1) {} + iterator begin() { return {this, 0}; } + void keys(); + void values(); +}; +void fn1() { + B<int, int, A<int>> m(fn1); + m.begin(); +}