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

Tiago Macarios via cfe-dev cfe-dev at lists.llvm.org
Tue Dec 6 16:54:33 PST 2016


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,

 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


On Tue, Dec 6, 2016 at 2:07 PM, Artem Dergachev <noqnoqneo at gmail.com> wrote:

> 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.
>
>
> On 12/7/16 12:42 AM, Tiago Macarios wrote:
>
>> 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"
>> )
>>
>> On Tue, Dec 6, 2016 at 11:59 AM, Artem Dergachev <noqnoqneo at gmail.com
>> <mailto:noqnoqneo at gmail.com>> wrote:
>>
>>     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>
>>         <mailto: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
>> >
>>                    <http://stackoverflow.com/que
>> stions/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 <mailto:cfe-dev at lists.llvm.org>
>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>         <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161206/c44ea328/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: preprocessed.zip
Type: application/zip
Size: 236687 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161206/c44ea328/attachment.zip>


More information about the cfe-dev mailing list