[cfe-dev] clang-analyzer NewDeleteLeaks : best way to silence a false positive

Jonathan Roelofs via cfe-dev cfe-dev at lists.llvm.org
Wed Jun 29 06:09:43 PDT 2016



On 6/28/16 6:14 PM, Benoit Belley via cfe-dev wrote:
> Hi everyone,
>
> The clang static analyzer gives a false positive warning on the
> following program:
>
>     $ cat falseLeak.cpp
>     struct CtrlBlk {
>         explicit CtrlBlk() : m_useCount(1) {}
>
>         virtual void dispose();
>
>         void decUseCount() {
>             -- m_useCount;
>             if (m_useCount == 0) { dispose(); }
>         }
>
>         int m_useCount;
>     };
>
>     struct Ptr {
>         Ptr() { m_cntrlBlk = new CtrlBlk; }
>         ~Ptr() { m_cntrlBlk->decUseCount(); }
>         CtrlBlk* m_cntrlBlk;
>     };
>
>     void testCase() { Ptr px; }
>
>
>     $ clang-tidy -checks=* falseLeak.cpp
>     1 warning generated.
>     /Users/benoit/tmp/falseLeak.cpp:20:27: warning: Potential leak of
>     memory pointed to by 'px.m_cntrlBlk'
>     [clang-analyzer-cplusplus.NewDeleteLeaks]
>     void testCase() { Ptr px; }
>                               ^
>     /Users/benoit/tmp/falseLeak.cpp:20:23: note: Calling default
>     constructor for 'Ptr'
>     void testCase() { Ptr px; }
>                           ^
>     /Users/benoit/tmp/falseLeak.cpp:15:26: note: Memory is allocated
>         Ptr() { m_cntrlBlk = new CtrlBlk; }
>                              ^
>     /Users/benoit/tmp/falseLeak.cpp:20:23: note: Returning from default
>     constructor for 'Ptr'
>     void testCase() { Ptr px; }
>                           ^
>     /Users/benoit/tmp/falseLeak.cpp:20:27: note: Potential leak of
>     memory pointed to by 'px.m_cntrlBlk'
>     void testCase() { Ptr px; }
>                               ^
>
>
> Here’s my solution to silence up that false positive:
>
>     #ifdef __clang_analyzer__
>         /// \brief Escape a variable from the analysis of the clang
>     static analyzer
>         ///
>         /// This function takes a reference to a variable as an
>     argument. This
>         /// causes the static analyzer tool to notice that the variable
>     has escape
>         /// the scope of its analysis. It forces the static analyzer to
>     make very
>         /// conservative assumptions about the state of the variable.
>     This also
>         /// includes assumptions about any memory location referenced by
>     this
>         /// variable.
>         ///
>         /// This can be used to silence up false positives. In general,
>     it is
>         /// better to augment the information available to the static
>     analyzer
>         /// using attributes and/or assertions. Unfortunately, this
>     isn't always
>         /// possible. For example, it might be impossible to describe
>     that a given
>         /// object is destructed along all execution paths.
>         template <typename V> static void
>     escapeFromClangStaticAnalysis(V& escapedVar);
>     #endif
>
>     struct CtrlBlk {
>         explicit CtrlBlk() : m_useCount(1) {}
>
>         virtual void dispose();
>
>         void decUseCount() {
>             -- m_useCount;
>             if (m_useCount == 0) { dispose(); }
>     #ifdef __clang_analyzer__
>             escapeFromClangStaticAnalysis(m_useCount);
>     #endif
>         }
>
>         int m_useCount;
>     };
>
>     struct Ptr {
>         Ptr() { m_cntrlBlk = new CtrlBlk; }
>         ~Ptr() { m_cntrlBlk->decUseCount(); }
>         CtrlBlk* m_cntrlBlk;
>     };
>
>     void testCase() { Ptr px; }
>
>
> Would anyone have a better solution ?

Does dispose() do `delete this`?

If so, I think the first problem is that the analyzer cannot possibly 
see that it does in this example.

Secondly, while legal, that's a very strange pattern, and it prevents 
you from using CtrlBlk with new[], placement new, as a stack variable, 
etc (i.e. if you call dispose(), you're only allowed to use it with 
plain old new).


Jon

>
> Thanks,
> Benoit
>
> *Benoit Belley*
>
> Sr Principal Developer
>
> M&E-Product Development Group
>
>
>
> *MAIN* +1 514 393 1616
>
> *DIRECT* +1 438 448 6304
>
> *FAX* +1 514 393 0110
>
>
>
> Twitter <http://twitter.com/autodesk>
>
> Facebook <https://www.facebook.com/Autodesk>
>
>
>
> *Autodesk, Inc.*
>
> 10 Duke Street
>
> Montreal, Quebec, Canada H3C 2L7
>
> www.autodesk.com <http://www.autodesk.com/>
>
>
>
> Description: Email_Signature_Logobar
>
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>

-- 
Jon Roelofs
jonathan at codesourcery.com
CodeSourcery / Mentor Embedded



More information about the cfe-dev mailing list