[cfe-dev] clang-tidy false positive cplusplus.NewDeleteLeaks

Tiago Macarios via cfe-dev cfe-dev at lists.llvm.org
Mon Dec 5 10:26:25 PST 2016


Hi,

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

Mac

On Thu, Dec 1, 2016 at 5:52 PM, Tiago Macarios <tiagomacarios at gmail.com>
wrote:

> 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 <QObject>
>
> 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.
>
>
>
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161205/32f0fc50/attachment.html>


More information about the cfe-dev mailing list