https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65188

Manuel López-Ibáñez <manu at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2015-02-24
                 CC|                            |manu at gcc dot gnu.org
            Summary|diagnostic: missing:        |improve error for member
                   |reference to non-static     |operator applied to
                   |member function must be     |non-class type
                   |called                      |
     Ever confirmed|0                           |1

--- Comment #1 from Manuel López-Ibáñez <manu at gcc dot gnu.org> ---
How does Clang message help in this case? The suggested fix 'c.f().a' will just
give 'invalid use of void type'

Of course, g++ could be better, as this testcase shows:

class C {
public:
  void g() {};
  C& f() {};
  int a;
} c;
void g2();
C&f2();
int foo(char **p, char **q) { return (p-q).a; }
int bar() { return c.f.a; }
int baz() { return c.g.a; }
int bar2() { return f2.a; }
int baz2() { return g2.a; }

g++:

test.cc:10:44: error: request for member ‘a’ in ‘((((long int)p) - ((long
int)q)) (ceiling /) 8l)’, which is of non-class type ‘long int’
 int foo(char **p, char **q) { return (p-q).a; }
                                            ^
test.cc: In function ‘int bar()’:
test.cc:11:20: error: ‘c.C::f’ does not have class type
 int bar() { return c.f.a; }
                    ^
test.cc: In function ‘int baz()’:
test.cc:12:20: error: ‘c.C::g’ does not have class type
 int baz() { return c.g.a; }
                    ^
test.cc: In function ‘int bar2()’:
test.cc:13:24: error: request for member ‘a’ in ‘f2’, which is of non-class
type ‘C&()’
 int bar2() { return f2.a; }
                        ^
test.cc: In function ‘int baz2()’:
test.cc:14:24: error: request for member ‘a’ in ‘g2’, which is of non-class
type ‘void()’
 int baz2() { return g2.a; }
                        ^
Possible improvements:

1) Consistency: all these errors should print the same message.

2) Location: the location should point to the expression that is not of class
type.

3) No pretty-printing of arbitrary expressions: If the expression is a name or
a declaration, print it; otherwise, print "request for member 'a' in expression
of non-class type 'long int'"

4) For types that have declarations, we could point to the declaration with a
note: 'c.C::f' declared here


For your testcase, it could be:

10.C:2:23: error: request for member in ‘c.C::f’, which is of non-class type
'void (C::)()'
 int main() { return c.f.a; }
                       ^
10.C:1:19: note: declared here
 class C { public: void f() {} } c;
                        ^

Reply via email to