llvm / llvm-project

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

False positive clang-analyzer-cplusplus.NewDelete for QWeakPointer when using `-isystem` flags #62985

Open timxx opened 1 year ago

timxx commented 1 year ago

For the following example code, run the Clang-Tidy as clang-tidy foo.cpp -- -isystem /usr/include/qt/QtCore/ -I/usr/include/qt/ (Suppose the Qt 5 headers installed at /usr/include/qt)

#include <QWeakPointer>

void test(const QWeakPointer<QObject>& p)
{
    QWeakPointer<QObject> t;
    t = p;
}

The following warning generated

1 warning generated.
/usr/include/qt/QtCore/qsharedpointer_impl.h:159:50: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
        inline void operator delete(void *ptr) { ::operator delete(ptr); }
                                                 ^

It's strange when using -I instead of -isystem, it won't report this problem, which is expected (Even using -header-filter=.*).

It can be reproduce on Windows platform too.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-static-analyzer

IvanArkhipov1999 commented 7 months ago

I got the same problem for clang-tidy-17 while using qt.

wcdbmv commented 6 months ago

Any news on this?

Snape3058 commented 3 months ago

Confirmed to be a bug in the malloc checker.

The false positive is due to the malloc checker considering all invocations to a delete operator defined/declared in system headers the ::operator delete. Hence, the statement delete this->d in the destructor of QWeakPointer will first mark this->d released before the call to QtSharedPointer::ExternalRefCountData::operator delete. Then, when inlining the call, the call to ::operator delete inside will report a UaF of this->d as it has already marked as released before the call.

I am working on fixing this bug. A temporary workaround can be using -I instead of -isystem to execute the analyzer. When using -I, the call to operator delete in the statement delete this->d will not be considered as in system headers.

Even using -header-filter=.*

@timxx This option is only effective for reports generated by clang-tidy, whereas the reports generated by clang static analyzer will not be filtered.