[cfe-dev] Recent regression in static analyzer

Miklos Vajna via cfe-dev cfe-dev at lists.llvm.org
Sat Jan 7 15:37:23 PST 2017


Hi,

Recent trunk of llvm + clang + clang-tools-extra started to fail on the
code below. git bisect (using the llvm-project repo) says:

----
5938113681837135a133a779d5f0e76c414198e2 is the first bad commit
commit 5938113681837135a133a779d5f0e76c414198e2
Author: Richard Smith <richard-llvm at metafoo.co.uk>
Date:   Wed Dec 14 00:03:17 2016 +0000

    Remove custom handling of array copies in lambda by-value array capture and
    copy constructors of classes with array members, instead using
    ArrayInitLoopExpr to represent the initialization loop.
    
    This exposed a bug in the static analyzer where it was unable to differentiate
    between zero-initialized and unknown array values, which has also been fixed
    here.

:040000 040000 876b416ac9168239b21cceefffc1da46d89c8424 ed30c61c2b9049285621eba3e33ac172ac5b787e M      clang
----

i.e. it seems this was introduced in r289618.

How to reproduce the problem:

----
$ clang-tidy -checks=-*,clang-analyzer-core.DivideZero test.cpp -- -std=c++11
'Assume' not implemented for this NonLoc
UNREACHABLE executed at /git/llvm/tools/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp:126!
Aborted (core dumped)
----

I just picked one check from clang-analyzer-core, it's not specific to
that given check. Do you have an idea what might be the problem there?

(In case it matters, this is a -DCMAKE_BUILD_TYPE=Release
-DLLVM_ENABLE_ASSERTIONS=ON build.)

And sorry for not making the sample more minimal, this code is
originally part of LibreOffice's filter/source/msfilter/rtfutil.cxx,
this is already a quite small part of the preprocessed source. :-)

Thanks a lot,

Miklos

----
#include <cstring>

struct String {};

struct Dummy {};

template< typename T1, typename T2 = void >
struct ConstCharArrayDetector {
};

template< std::size_t N, typename T >
struct ConstCharArrayDetector< const char[ N ], T > {
    typedef T Type;
    static const std::size_t length = N - 1;
};

template< typename T, bool >
struct Enable { };

template< typename T1, typename T2 >
struct Concat {
    public:
        Concat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
        int length() const { return 0; }
    private:
        const T1& left;
        const T2& right;
};

template< typename T, int N >
inline T operator+( const T& left, const char (&right)[ N ] ) {
    return Concat< T, const char[ N ] >( left, right );
}

struct OString {
    String * pData;

    template< typename T >
    OString( T&, typename ConstCharArrayDetector< T, Dummy >::Type = Dummy() ) {}

    template< typename T1, typename T2 >
    OString( const Concat< T1, T2 >& ) {}

};

OString f()
{
    return OString("{") + "}";
}
----



More information about the cfe-dev mailing list