Menu

Analysis failed (Cppcheck 1.82)

Set
2018-02-13
2018-03-23
  • Set

    Set - 2018-02-13

    Cppcheck 1.82 failed running analysis of the following simplified code:

    #define EVTDELEG(classname,arg1type) template<typename T>\
    class C##classname {\
    public:\
        typedef void (T::*fnptr)(##arg1type);\
        C##classname( T* object, fnptr fn ) : m_object(object), m_fn(fn) { }\
        void Invoke( ##arg1type value ) {\
            (m_object->*m_fn)( value );\
        }\
    private:\
        T*      m_object;\
        fnptr   m_fn;\
    };
    
    class EvtH {
        // For each of the events a delegate needs to be declared.
        EVTDELEG(CDG, bool)
    };
    
    void main() {
        return 0;
    }
    

    Online demo (http://cppcheck.sourceforge.net/demo/) reports:

    Cppcheck 1.82
    
    [test.cpp:15]: (error) Analysis failed. If the code is valid then please report this failure.
    
    Done!
    

    I tried to create a ticket in Trac, but I was not able to create an account (tried https://webchat.freenode.net/?channels=#cppcheck and then also this forum: https://sourceforge.net/p/cppcheck/discussion/development/thread/34ddb3ae/#5be5).

     
  • versat

    versat - 2018-02-13

    How do you compile this code?
    I tried g++ 6.4.0 with "g++ --std=c++17 analysis_failed.cpp" and got the following output:

    analysis_failed.cpp:4:29: error: pasting "(" and "bool" does not give a valid preprocessing token
         typedef void (T::*fnptr)(##arg1type);\
                                 ^
    analysis_failed.cpp:16:5: note: in expansion of macro EVTDELEG
         EVTDELEG(CDG, bool)
         ^~~~~~~~
    analysis_failed.cpp:6:16: error: pasting "(" and "bool" does not give a valid preprocessing token
         void Invoke( ##arg1type value ) {\
                    ^
    analysis_failed.cpp:16:5: note: in expansion of macro EVTDELEG
         EVTDELEG(CDG, bool)
         ^~~~~~~~
    analysis_failed.cpp:19:11: error: ::main must return int
     void main() {
               ^
    
     
  • Set

    Set - 2018-02-28

    Thank you for the response. I am sorry for the delay (I had a vacation).
    You are correct. With simplification of the original code I left return 0; while main() is void. Just replace void with int and this code compiles. I am using Visual Studio 2015 (C++ CLR). Nevertheless, CPPCheck should not fail such way despite the code is not compilable.

     
  • versat

    versat - 2018-03-05

    Ah ok, with Visual Studio i also do not get the preprocessor errors.
    GCC and Visual Studio handle the token pasting operator differently:
    According to https://complete-concrete-concise.com/programming/c/preprocessor-the-token-pasting-operator both compilers are working correctly, the standard does not define everything.
    So i think Cppcheck should handle this code correctly too and should not issue an analysis failed warning.
    I will create a ticket for that.

     
  • versat

    versat - 2018-03-05
     
  • Set

    Set - 2018-03-06

    Thank you. Nevertheless, amai marked this as a duplicate ticket and closed it. I hope that the developers will finally take care about it.

     
  • versat

    versat - 2018-03-06

    It seems to be really a duplicate of his older ticket and there the result was that it seems to be invalid code.
    If you have any information/links that this is really valid code that should be accepted by static analyzers that may help.

     
  • Daniel Marjamäki

    Please tell me why you have the ## in the code :

    typedef void (T::*fnptr)(##arg1type);
    

    Is it by mistake?

    This usage of ## seems pointless to me and it makes the code invalid/undefined.

     
  • Set

    Set - 2018-03-08

    I agree, you are right. ## is useless in this case. It concatenates an empty token with a token arg1type. Anyway, it is compilable by Visual Studio (at least 2017, without any error or warning).
    This is a simplified fragment of a legacy code in our huge stream which is going to be replaced soon (I hope). Nevertheless, the point I wrote about this is that I considered Cppcheck encountered a serious internal error (because it "failed") which is good to report. Failure of a program represents a backlog from my point of view - therefore I just wanted to inform about such an issue to help to improve the behaviour of future versions of Cppcheck. It could inform the user in a better way than with a failure in my opinion.

     
  • Daniel Marjamäki

    For information, I want simplecpp to be compatible with gcc/msvc.. but this feels like a bug in the msvc preprocessor so I will not try to implement this.

    It could inform the user in a better way than with a failure in my opinion.

    Yes I totally agree. I created this issue: https://github.com/danmar/simplecpp/issues/121

     
  • Set

    Set - 2018-03-22

    Ok. I have something else now. The following code gives: "[test.cpp:13]: (error) Array 'pdispparams->rgvarg[2]' accessed at index 2, which is out of bounds." This error message is suppressed if another assert() is added (just uncomment the last assert and you will see). I do not undersand the behaviour of CPPCheck here.

    The following fragment of code is compilable in VS2017.

    #include <atlbase.h>
    #include <assert.h>
    
    class CBBox {
    public:
        CBBox() {}
        STDMETHOD(Invoke)(DISPPARAMS* pdispparams, VARIANT*) {
            assert(pdispparams->cArgs == 3);
            assert(pdispparams->rgvarg[0].vt == VT_R8);
            assert(pdispparams->rgvarg[1].vt == VT_I4);
            assert(pdispparams->rgvarg[2].vt == VT_BSTR);
            //assert(pdispparams->rgvarg[3].vt == VT_BSTR); // Uncommenting this line suppresses the error message of the line below
            CComBSTR name = pdispparams->rgvarg[2].bstrVal;
            return S_OK;
        }
    };
    
    int main() {
        return 0;
    }
    
     
  • versat

    versat - 2018-03-23

    I can reproduce this with the current development version of Cppcheck:

    $ ./cppcheck --debug-warnings array_outofbounds.cpp
    Checking array_outofbounds.cpp ...
    [array_outofbounds.cpp:13]: (error) Array 'pdispparams->rgvarg[2]' accessed at index 2, which is out of bounds.
    [array_outofbounds.cpp:8]: (debug) Unknown type 'pdispparams.'.
    [array_outofbounds.cpp:11]: (debug) Unknown type 'pdispparams.'.
    

    IMHO the error is a false positive and i have no idea how Cppcheck knows (or think it knows) the size of the array pdispparams->rgvarg[]. I am not sure but guessing such things out of asserts is not yet implemented and even if it would be i can not see how this error is justified then.

    But i am no insider so maybe one of the core developers has an idea what is going on here.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.