[Bug c++/53281] poor error message for calling a non-const method from a const object

2022-05-26 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #15 from Jonathan Wakely  ---
Created attachment 53035
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53035=edit
Incomplete patch

[Bug c++/53281] poor error message for calling a non-const method from a const object

2022-05-24 Thread barry.revzin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Barry Revzin  changed:

   What|Removed |Added

 CC||barry.revzin at gmail dot com

--- Comment #14 from Barry Revzin  ---
Following up on this (and a lot of the ideas presented here are I think better
than "passing [...] discards qualifiers")...

This:

struct B {
void f();
}; 

struct D : B {
void const_f() const {
f();
}
};

gives me that same error:

:8:10: error: passing 'const D' as 'this' argument discards qualifiers
[-fpermissive]
8 | f();
  | ~^~
:2:10: note:   in call to 'void B::f()'
2 | void f();
  |  ^

But this slight difference (D is now a template, though B is a non-dependent
base):

struct B {
void f();
}; 

template 
struct D : B {
void const_f() const {
f();
}
};

instead emits: 

:8:10: error: cannot convert 'const D*' to 'B*'
8 | f();
  | ~^~
:2:10: note:   initializing argument 'this' of 'void B::f()'
2 | void f();
  |  ^

Which is... technically correct, that is the problem, but now that I'm used to
seeing the "discards qualifiers" error, this one really threw me for a loop. 

It'd be nice at the very least if these two examples gave the same error

[Bug c++/53281] poor error message for calling a non-const method from a const object

2021-04-19 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jonathan Wakely  changed:

   What|Removed |Added

 Status|ASSIGNED|NEW
   Target Milestone|11.0|---
   Assignee|redi at gcc dot gnu.org|unassigned at gcc dot 
gnu.org

[Bug c++/53281] poor error message for calling a non-const method from a const object

2020-03-12 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jonathan Wakely  changed:

   What|Removed |Added

   Target Milestone|9.4 |11.0

[Bug c++/53281] poor error message for calling a non-const method from a const object

2020-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.3 |9.4

--- Comment #13 from Jakub Jelinek  ---
GCC 9.3.0 has been released, adjusting target milestone.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2019-08-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.2 |9.3

--- Comment #12 from Jakub Jelinek  ---
GCC 9.2 has been released.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2019-05-03 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.0 |9.2

--- Comment #11 from Jakub Jelinek  ---
GCC 9.1 has been released.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-05-29 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #10 from Jonathan Wakely  ---
My patch fails to account for ref-qualifiers on the member function, so needs
some improvement.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-05-29 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #9 from Jonathan Wakely  ---
N.B. comment 6 is the subject of PR 85958 which is really a different bug to
this one. This is about invalid member function calls on cv-qualified objects,
and 85958 is about invalid attempts to bind references to cv-qualified objects.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-23 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jonathan Wakely  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|dmalcolm at gcc dot gnu.org|redi at gcc dot gnu.org

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-19 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #8 from Jonathan Wakely  ---
(In reply to David Malcolm from comment #6)
> It seems best to special-case the "const member fn/param called with
> non-const" cases and to report them directly in terms of the types in user's
> source with and without "const", and to be explicit about which qualifier(s)
> are lost.

Don't forget 'volatile', which is rarely used for member function qualifiers,
but we might as well handle both at once (as my patches above do).


> Proposed output for the case in comment #3:
> 
> cv.cc: In member function ‘void Foo::bar2(const Foo&)’:
> cv.cc:4:26: error: passing ‘const Foo’ as ‘this’ argument discards 'const'
> qualifier [-fpermissive]
>  foo.bar1();
>   ^
> cv.cc:2:14: note:   in call to ‘void Foo::bar1()’ which is non-const
>  void bar1() {}
>   ^~~~

This has a number of problems, see comment 5 for discussion and a patch.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-18 Thread dmalcolm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #7 from David Malcolm  ---
(In reply to David Malcolm from comment #6)
[...]
> We should also underline the param, or the "const" token.
(actually, if the member function or param is 'const', it's not a problem, I
think.  -ENOCOFFEE)

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-18 Thread dmalcolm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

David Malcolm  changed:

   What|Removed |Added

 CC||dmalcolm at gcc dot gnu.org
   Assignee|unassigned at gcc dot gnu.org  |dmalcolm at gcc dot 
gnu.org
   Target Milestone|--- |9.0

--- Comment #6 from David Malcolm  ---
Another example, given by reddit user "agcpp" here:
https://www.reddit.com/r/cpp/comments/84op5c/usability_improvements_in_gcc_8/dvvry8y/

> I'm little late to the party but want to add another example
> where diagnostics will improve overall experience -
> https://godbolt.org/g/kGKowz
>
> The diagnostics produced by MSVC here are just perfect, clang does
> seem a bit verbose but readable otoh gcc confuses anyone who
> hasn't been writing c++ for about 5 years :D



Code at that godbolt link:

#include 
using std::string;

void func(string ) {
s.clear();
}

int main() {
const string s = "20";
func(s);
}



MSVC 19 2017:

/opt/compiler-explorer/windows/19.10.25017/lib/native/include/xlocale(314):
warning C4530: C++ exception handler used, but unwind semantics are not
enabled. Specify /EHsc
(10): error C2664: 'void func(std::string &)': cannot convert argument
1 from 'const std::string' to 'std::string &'
(10): note: Conversion loses qualifiers



clang trunk:

:10:5: error: no matching function for call to 'func'
func(s);
^~~~
:4:6: note: candidate function not viable: 1st argument ('const
std::__cxx11::string' (aka 'const basic_string')) would lose const
qualifier
void func(string ) {
 ^
1 error generated.
Compiler returned: 1



gcc trunk:

: In function 'int main()':
:10:10: error: binding reference of type 'std::__cxx11::string&' {aka
'std::__cxx11::basic_string&'} to 'const string' {aka 'const
std::__cxx11::basic_string'} discards qualifiers
 func(s);
  ^
:4:6: note:   initializing argument 1 of 'void
func(std::__cxx11::string&)'
 void func(string ) {
  ^~~~
Compiler returned: 1



Part of the verbosity here relates to PR c++/84897 (reporting std::string
rather than std::__cxx11::string).

We're emitting a 28 words/~170 chars to seemingly talk about how:

  Compiler: "did you know that std::string is actually a
std::basic_string?"  mumble mumble, something
about a qualifier.

where the user has to spot the most pertinent word: "const" appearing in the
2nd pair of types, absent in the 1st pair of types.

Among other issues, the aka seems redundant/unhelpful here.

It seems best to special-case the "const member fn/param called with non-const"
cases and to report them directly in terms of the types in user's source with
and without "const", and to be explicit about which qualifier(s) are lost.

We should also underline the param, or the "const" token.

Proposed output for the above:

error: binding reference of type 'std::string&' to 'const string' discards
'const' qualifier
 func(s);
  ^
note:   initializing non-'const' argument 1 of 'void func(std::string&)'
 void func(string ) {
   ~~~^~

(though even that is a bit "compiler-ese"; might want to talk about it being a
call up-front)

Proposed output for the case in comment #3:

cv.cc: In member function ‘void Foo::bar2(const Foo&)’:
cv.cc:4:26: error: passing ‘const Foo’ as ‘this’ argument discards 'const'
qualifier [-fpermissive]
 foo.bar1();
  ^
cv.cc:2:14: note:   in call to ‘void Foo::bar1()’ which is non-const
 void bar1() {}
  ^~~~

I hope to fix these for gcc 9.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-06 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #5 from Jonathan Wakely  ---
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 % "
-"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);
}


cv.cc: In member function 'void Foo::bar2(const Foo&)':
cv.cc:4:26: error: cannot call non-const member function on object of type
'const Foo' [-fpermissive]
 foo.bar1();
  ^
cv.cc:2:14: note:   in call to 'void Foo::bar1()'
 void bar1() {}
  ^~~~

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-06 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #4 from Jonathan Wakely  ---
FWIW Clang says:

cv.cc:4:17: error: member function 'bar1' not viable: 'this' argument has type
'const Foo', but function is not marked const
foo.bar1();
^~~
cv.cc:2:14: note: 'bar1' declared here
void bar1() {}
 ^
1 error generated.


And EDG says:

"cv.cc", line 4: error: the object has type qualifiers that are not compatible
  with the member function
object type is: const Foo
  foo.bar1();
  ^

1 error detected in the compilation of "cv.cc".

[Bug c++/53281] poor error message for calling a non-const method from a const object

2018-03-06 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #3 from Jonathan Wakely  ---
Current trunk gives:

cv.cc: In member function ‘void Foo::bar2(const Foo&)’:
cv.cc:4:26: error: passing ‘const Foo’ as ‘this’ argument discards qualifiers
[-fpermissive]
 foo.bar1();
  ^
cv.cc:2:14: note:   in call to ‘void Foo::bar1()’
 void bar1() {}
  ^~~~


With this patch:

--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7799,7 +7799,24 @@ build_over_call (struct z_candidate *cand, int flags,
tsubst_flags_t complain)
  if (permerror (input_location, "passing %qT as % "
 "argument discards qualifiers",
 TREE_TYPE (argtype)))
-   inform (DECL_SOURCE_LOCATION (fn), "  in call to %qD", fn);
+   {
+ 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;
+ const char *descr;
+ if (non_const && non_volatile)
+   descr = " which is non-const and non-volatile";
+ else if (non_const)
+   descr = " which is non-const";
+ else if (non_volatile)
+   descr = " which is non-volatile";
+ else
+   descr = "";
+ inform (DECL_SOURCE_LOCATION (fn), "  in call to %qD%s",
+ fn, descr);
+   }
}
  else
return error_mark_node;


we get:

cv.cc: In member function ‘void Foo::bar2(const Foo&)’:
cv.cc:4:26: error: passing ‘const Foo’ as ‘this’ argument discards qualifiers
[-fpermissive]
 foo.bar1();
  ^
cv.cc:2:14: note:   in call to ‘void Foo::bar1()’ which is non-const
 void bar1() {}
  ^~~~

Note the addition of "which is non-const" to the note.

[Bug c++/53281] poor error message for calling a non-const method from a const object

2012-05-09 Thread redi at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

Jonathan Wakely redi at gcc dot gnu.org changed:

   What|Removed |Added

   Keywords||diagnostic
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2012-05-09
 Ever Confirmed|0   |1

--- Comment #2 from Jonathan Wakely redi at gcc dot gnu.org 2012-05-09 
15:59:09 UTC ---
confirmed (but any change to the diagnostic should not mention the word 
method because C++ has member functions not methods)


[Bug c++/53281] poor error message for calling a non-const method from a const object

2012-05-08 Thread rui.maciel at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53281

--- Comment #1 from Rui Maciel rui.maciel at gmail dot com 2012-05-08 
13:27:24 UTC ---
The same suggestion applies to the cases where a non-const method is called
from a const method, such as in the example below:

code
class Foo {
void bar1() {}
void bar2() const {
bar1();
}
};

int main()
{
return 0;
}
/code

The same error message is returned:
message
main.c++: In member function ‘void Foo::bar2() const’:
main.c++:4:22: error: passing ‘const Foo’ as ‘this’ argument of ‘void
Foo::bar1()’ discards qualifiers [-fpermissive]
/message