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();
+}

Reply via email to