clang-tidy false positive cplusplus.NewDeleteLeaks

Hi,

First time poster so I hope I get the etiquette right.

I am trying to use clang-tidy (3.9.1) with a Qt (5.7) project and I am getting a false positive memory leak.

Here is the CMake file:

cmake_minimum_required(VERSION 3.2)
project(main)
add_executable(main main.cpp)

set_target_properties(main

PROPERTIES
CXX_STANDARD 14
CXX_EXTENSIONS OFF
AUTOMOC ON
AUTOUIC ON
CXX_CLANG_TIDY
“clang-tidy”
“-checks=modernize-,readability-,performance-*”
“-fix”
)
find_package(Qt5Core)

target_link_libraries(main Qt5::Core)

Here is the main.cpp (it is the minimum amount of code to reproduce the issue, the code itself is brain-dead):

#include

int main(int argc, char *argv[])
{
QObject a;
QObject::connect(&a, &QObject::destroyed, {});

return 0;

}

clang-tidy will display the following warning:

/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:343:16: warning: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
^
/mnt/e/_Working/tidy/main.cpp:8:5: note: Calling ‘QObject::connect’
QObject::connect(&a, &QObject::destroyed, {});
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:293:16: note: Calling ‘QObject::connect’
return connect(sender, signal, sender, slot, Qt::DirectConnection);
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:308:39: note: ‘?’ condition is true
const int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:340:13: note: Left side of ‘||’ is false
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:340:9: note: Taking false branch
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:344:28: note: Memory is allocated
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
^
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:343:16: note: Potential memory leak
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
^

Here is the code it refers to QtCore/qobject.h:343:

return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);

The object created by that new, does get properly destroyed. This seems to happen at tCore\qobject_impl.h:168:

static void impl(int which, QSlotObjectBase *this_, QObject *r, void *a, bool ret)
{
switch (which) {
case Destroy:
delete static_cast<QFunctorSlotObject
>(this_); //HERE
break;
case Call:
FuncType::template call<Args, R>(static_cast<QFunctorSlotObject
>(this_)->function, r, a);
break;
case Compare: // not implemented
case NumOperations:
Q_UNUSED(ret);
}
}

From a naive perspective it seems like that false positive leak would be pretty hard to catch. So I guess the best solution (at the moment) would be for me to silence the error. (Please someone correct me if I am wrong).

Googling around I found two different ways to silence this false positives:
// NOLINT
#ifndef clang_analyzer

I tried to use both in multiple ways, see this SO post: http://stackoverflow.com/questions/40642307/silencing-clang-tidy
But I still haven’t figured out a way to silence this error. Maybe someone can help me figure this one out?

FYI: QObject::connect is used all over Qt code. So I would rather patch the Qt source files, then have to annotate every call to that function.

Mac.

Hi,

If this is the wrong mail-list could someone point me to the correct one please?

Mac

Whoops sorry missed this message!

This is (or looks like) a false positive for the clang static analyzer's MallocChecker (clang-tidy runs the analyzer internally, but is not responsible for this checker directly).

I think we should investigate that, and a preprocessed file with an -analyze/--analyze command line would speed us up significantly :slight_smile:

Hi Artem,

Thanks for the email. Could you let me know exactly what you need?

If I run clang with the --analyze flag I get a simpler log than the one clang-tidy generates (same problem though):


[ 75%] Building CXX object CMakeFiles/main.dir/main_automoc.cpp.o
In file included from /mnt/e/_working/tidy/main.cpp:2:
In file included from /opt/Qt5.7.0/5.7/gcc_64/include/QtCore/QObject:1:
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:343:16: warning: Potential memory leak
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
[100%] Linking CXX executable main
clang: warning: CMakeFiles/main.dir/main.cpp.o: ‘linker’ input unused
clang: warning: CMakeFiles/main.dir/main_automoc.cpp.o: ‘linker’ input unused
clang: warning: /opt/Qt5.7.0/5.7/gcc_64/lib/libQt5Core.so.5.7.0: ‘linker’ input unused
clang: warning: -Wl,-rpath,/opt/Qt5.7.0/5.7/gcc_64/lib: ‘linker’ input unused
clang: warning: argument unused during compilation: ‘-rdynamic’
make[3]: Leaving directory ‘/mnt/e/_working/tidy/build/linux’

I modified the original cmake file to this:

SET(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} --analyze”)

set_target_properties(main
PROPERTIES
CXX_STANDARD 14
CXX_EXTENSIONS OFF
AUTOMOC ON
AUTOUIC ON

CXX_CLANG_TIDY

“clang-tidy”

“-checks=modernize-,readability-,performance-*”

“-fix”

)

Could you run `clang` with flag `-E` to obtain a preprocessed file, and then demonstrate the problem by running `clang --analyze` (probably with some flags) on that file? That'd be really great.

There must be some pointer-escape that we're missing. Hmm, it's not the first time Qt turns out to be difficult for the analyzer to handle.

I think i should be able to figure out how to suppress the warning from the preprocessed file even if the fix would take some time.

Ok got it. File attached.

Command line used to generate it:

/usr/bin/clang++
-E
-isystem /opt/Qt5.7.0/5.7/gcc_64/include
-isystem /opt/Qt5.7.0/5.7/gcc_64/include/QtCore
-fPIC
-std=c++14
-c main.cpp
-o preprocessed.cpp

To compile:

/usr/bin/clang++
–analyze
-DQT_CORE_LIB
-DQT_NO_DEBUG
-fPIC
-std=c++14
-c preprocessed.cpp

Shows the same warning:

In file included from main.cpp:2:
In file included from /opt/Qt5.7.0/5.7/gcc_64/include/QtCore/QObject:1:
/opt/Qt5.7.0/5.7/gcc_64/include/QtCore/qobject.h:343:16: warning: Potential memory leak
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, nullptr,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

preprocessed.zip (231 KB)

Thanks for reporting this!! Reproduced.

Hey Arten,

I understand that a fix might take a while, but would it be possible for you to help me suppress the warning?

Tiago

Proposing a hacky fix in: https://reviews.llvm.org/D27717