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

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Tue Dec 6 11:59:58 PST 2016


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 :)

On 12/5/16 9:26 PM, Tiago Macarios via cfe-dev wrote:
> 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 <mailto: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
>     <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.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list