llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.84k stars 11.91k forks source link

Strangely worded error message "reference to non-static member function must be called" #19369

Open eschnett opened 10 years ago

eschnett commented 10 years ago
Bugzilla Link 18995
Version 3.4
OS MacOS X
CC @DougGregor,@zygoloid

Extended Description

I received the following error message for C++ code:

      reference to non-static member function must be called
            static_cast<derived const *>(this)->eigenvalues<direction>(

The caret points to the e of eigenvalues.

Although I am familiar with C++, I do not understand the wording of this error message. I think the wording can be improved.

The immediate meaning seems to be that there is a non-static member function, and that one must call it, implying that I am trying to do something else with it. That is wrong; I am actually trying to call it.

I assume that this message wants to say "This looks like a function call for a non-static member function, but this is not actually a non-static member function." Additionally, it could tell me what eigenvalues<direction> actually is.

In this case, the issue is that eigenvalues exists in both this class and its superclass, and the C-style cast to the superclass is not accepted by Clang. (Other compilers accepted it.)

Could you improve the wording of the error message?

llvmbot commented 8 years ago

This appears to be a duplicate of bug llvm/llvm-project#13938 .

eschnett commented 10 years ago

Sorry, I was confused.

The problem was a missing template keyword before the name eigenvalues. The new (accepted by clang) code is

        template<policy::direction_t direction>
        inline void eigenvalues(
                //! [in, out] local value of all the variables
                Observer<CLaw<derived> > & observer
                ) const {
            static_cast<derived const*>(this)->
              template eigenvalues<direction>(observer);
        }

where I added the keyword template.

Without this keyword, the complete diagnostic is:

/Users/eschnett/Cbeta/arrangements/DGFE/HRSCCore/src/hrscc_claw.hh:104:48: error: 
      reference to non-static member function must be called
            static_cast<derived const*>(this)->eigenvalues<direction>(observer);
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~

followed by many notes describing the instantiation chain.

As you describe, the underlined portion does not include the template argument. This escaped my attention because the called routine is a template, and I call it as a template, but since the type name "derived" depends on the template parameter one needs the template keyword.

I tried to come up with a reduced test case for my code, but failed. However, your test case produces the same error message and behaviour, so I hope this suffices.

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 10 years ago

The immediate meaning seems to be that there is a non-static member function, and that one must call it, implying that I am trying to do something else with it. That is wrong; I am actually trying to call it.

I suspect the issue is that eigenvalues is not a template. Can you provide a testcase, and also the complete diagnostic produced? Here's one way to get the same diagnostic you're seeing:

  struct X { void eigenvalues(); };
  void g(X x) { x.eigenvalues<0>(); }

... and in this case we underline eigenvalues but not the <0>, suggesting (though probably not clearly enough) that the member function we're talking about doesn't include the <0> part.

In this case, the issue is that "eigenvalues" exists in both this class and its superclass, and the C-style cast to the superclass is not accepted by Clang. (Other compilers accepted it.)

I don't follow: your example doesn't contain a C-style cast, and its static_cast is to derived const *.