--- Comment #5 from Jonathan Wakely <redi at gcc dot> ---
A further improvement might be to stop talking about "passing '...' as 'this'
argument" since that's a leaky abstraction: although member functions are
implemented with a hidden 'this' parameter, that's not how most C++ programmers
think of it, or how the abstract machine is described. Also, 'this' is a
pointer, and 'const Foo' is not a pointer type (Clang loses points there too).

So maybe this would be better:

--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7796,8 +7796,15 @@ build_over_call (struct z_candidate *cand, int flags,
tsubst_flags_t complain)
          if (complain & tf_error)
-             if (permerror (input_location, "passing %qT as %<this%> "
-                            "argument discards qualifiers",
+             int argquals = cp_type_quals (TREE_TYPE (argtype));
+             int fnquals = cp_type_quals (TREE_TYPE (fn));
+             int discarded = argquals & ~fnquals;
+             bool non_const = discarded & TYPE_QUAL_CONST;
+             bool non_volatile = discarded & TYPE_QUAL_VOLATILE;
+             if (permerror (input_location, "cannot call %s%s member "
+                            "function on object of type %qT",
+                            non_const ? "non-const" : "",
+                            non_volatile ? "non-volatile" : "",
                             TREE_TYPE (argtype)))
                inform (DECL_SOURCE_LOCATION (fn), "  in call to %qD", fn);
            } In member function 'void Foo::bar2(const Foo&)': error: cannot call non-const member function on object of type
'const Foo' [-fpermissive]
                          ^ note:   in call to 'void Foo::bar1()'
         void bar1() {}

Reply via email to