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

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Tue Dec 6 23:41:09 PST 2016


Thanks for reporting this!! Reproduced.

On 12/7/16 3:54 AM, Tiago Macarios wrote:
> 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 
> <mailto: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>
>         <mailto: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>>
>                 <mailto: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/questions/40642307/silencing-clang-tidy
>         <http://stackoverflow.com/questions/40642307/silencing-clang-tidy>>
>                          
>          <http://stackoverflow.com/questions/40642307/silencing-clang-tidy
>         <http://stackoverflow.com/questions/40642307/silencing-clang-tidy>
>                
>         <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 <mailto:cfe-dev at lists.llvm.org>
>         <mailto: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>
>                
>         <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>         <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>>
>
>
>
>
>




More information about the cfe-dev mailing list