<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-CA link=blue vlink=purple><div class=WordSection1><p class=MsoNormal>Hi,<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>This is my first post to this list. I hope someone here can help.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I have built LLVM and Clang from source (SVN trunk head today) using Mingw/MSYS and CMake in order to use the static analyzer to check some C code. <o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>To test my builds I have been using the source files for AStyle as a test case. I added a unpaired malloc call to astyle_main.cpp to ensure a bug would be found. The static analyzer is functioning and detects that bug (as well as a couple of other “values stored is not read” errors).<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>In earlier test runs a few days ago the static analyzer found what I believe is a real bug in the AStyle source and gave me a nice memory is never released report with HTML etc which I printed. Since then I have rebuilt LLVM and Clang several times (while changing build tools etc.). Now I no longer get the same bug report for that section of code.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The code is question is fairly short so I have copied it below. It does two allocations, but doesn’t free the first allocation if the second fails. I believe the delete [] outBuf that I have commented out below is required for correct operation without a memory leak.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>string ASConsole::getNumberFormat(int num, size_t lcid) const<o:p></o:p></p><p class=MsoNormal>{<o:p></o:p></p><p class=MsoNormal>                // Compilers that don't support C++ locales should still support this assert.<o:p></o:p></p><p class=MsoNormal>                // The C locale should be set but not the C++.<o:p></o:p></p><p class=MsoNormal>                // This function is not necessary if the C++ locale is set.<o:p></o:p></p><p class=MsoNormal>                assert(locale().name() == "C");<o:p></o:p></p><p class=MsoNormal>                // convert num to a string<o:p></o:p></p><p class=MsoNormal>                stringstream alphaNum;<o:p></o:p></p><p class=MsoNormal>                alphaNum << num;<o:p></o:p></p><p class=MsoNormal>                string number = alphaNum.str();<o:p></o:p></p><p class=MsoNormal>                if (useAscii)<o:p></o:p></p><p class=MsoNormal>                                return number;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // format the number using the Windows API<o:p></o:p></p><p class=MsoNormal>                if (lcid == 0)<o:p></o:p></p><p class=MsoNormal>                                lcid = LOCALE_USER_DEFAULT;<o:p></o:p></p><p class=MsoNormal>                int outSize = ::GetNumberFormat(lcid, 0, number.c_str(), NULL, NULL, 0);<o:p></o:p></p><p class=MsoNormal>                char* outBuf = new(nothrow) char[outSize];<o:p></o:p></p><p class=MsoNormal>                if (outBuf == NULL)<o:p></o:p></p><p class=MsoNormal>                                return number;<o:p></o:p></p><p class=MsoNormal>                ::GetNumberFormat(lcid, 0, number.c_str(), NULL, outBuf, outSize);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // remove the decimal<o:p></o:p></p><p class=MsoNormal>                string formattedNum(outBuf);<o:p></o:p></p><p class=MsoNormal>                int decSize = ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, NULL, 0);<o:p></o:p></p><p class=MsoNormal>                char* decBuf = new(nothrow) char[decSize];<o:p></o:p></p><p class=MsoNormal>                if (decBuf == NULL) {<o:p></o:p></p><p class=MsoNormal>                                // delete [] outBuf;<o:p></o:p></p><p class=MsoNormal>                                return number;<o:p></o:p></p><p class=MsoNormal>                }<o:p></o:p></p><p class=MsoNormal>                ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, decBuf, decSize);<o:p></o:p></p><p class=MsoNormal>                size_t i = formattedNum.rfind(decBuf);<o:p></o:p></p><p class=MsoNormal>                if (i != string::npos)<o:p></o:p></p><p class=MsoNormal>                                formattedNum.erase(i);<o:p></o:p></p><p class=MsoNormal>                if (!formattedNum.length())<o:p></o:p></p><p class=MsoNormal>                                formattedNum = "0";<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                delete [] outBuf;<o:p></o:p></p><p class=MsoNormal>                delete [] decBuf;<o:p></o:p></p><p class=MsoNormal>                return formattedNum;<o:p></o:p></p><p class=MsoNormal>}<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>One possibility is that the code is not compiled at all during the static analyzer build. This function inside a #ifdef _WIN32/#endif pair. I don’t know why the definition would have changed, but I suspect it has. <o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>To check I preprocessed  the file and I can see that _WIN32 is defined, at least by g++.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>$ g++ -E -dM ../../src/astyle_main.cpp | grep -i "_win32"<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32_NT 2<o:p></o:p></p><p class=MsoNormal>#define FACILITY_WIN32 7<o:p></o:p></p><p class=MsoNormal>#define _WIN32_WINNT WINVER<o:p></o:p></p><p class=MsoNormal>#define LHashValOfName(l,n) LHashValOfNameSys(SYS_WIN32,l,n)<o:p></o:p></p><p class=MsoNormal>#define __GTHREAD_HIDE_WIN32API 1<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32_OWN_PROCESS 16<o:p></o:p></p><p class=MsoNormal>#define WIN32 1<o:p></o:p></p><p class=MsoNormal>#define _WIN32 1<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32_SHARE_PROCESS 32<o:p></o:p></p><p class=MsoNormal>#define __WIN32__ 1<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS|SERVICE_WIN32_SHARE_PROCESS)<o:p></o:p></p><p class=MsoNormal>#define __WIN32 1<o:p></o:p></p><p class=MsoNormal>#define __RPC_WIN32__<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32_WINDOWS 1<o:p></o:p></p><p class=MsoNormal>#define SERVICE_TYPE_ALL (SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS)<o:p></o:p></p><p class=MsoNormal>#define HRESULT_FROM_WIN32(x) (x?((HRESULT)(((x)&0x0000FFFF)|(FACILITY_WIN32<<16)|0x80000000)):0)<o:p></o:p></p><p class=MsoNormal>#define GCC_GTHR_WIN32_H<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32s 0<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So I repeated with clang++ in case the wrong compiler is being used for the build, but it defines _WIN32 as well<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>$ clang++ -E -dM ../../src/astyle_main.cpp | grep -i "win32"<o:p></o:p></p><p class=MsoNormal>#define FACILITY_WIN32 7<o:p></o:p></p><p class=MsoNormal>#define GCC_GTHR_WIN32_H<o:p></o:p></p><p class=MsoNormal>#define HRESULT_FROM_WIN32(x) (x?((HRESULT)(((x)&0x0000FFFF)|(FACILITY_WIN32<<16)|0x80000000)):0)<o:p></o:p></p><p class=MsoNormal>#define LHashValOfName(l,n) LHashValOfNameSys(SYS_WIN32,l,n)<o:p></o:p></p><p class=MsoNormal>#define SERVICE_TYPE_ALL (SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS)<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS|SERVICE_WIN32_SHARE_PROCESS)<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32_OWN_PROCESS 16<o:p></o:p></p><p class=MsoNormal>#define SERVICE_WIN32_SHARE_PROCESS 32<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32_NT 2<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32_WINDOWS 1<o:p></o:p></p><p class=MsoNormal>#define VER_PLATFORM_WIN32s 0<o:p></o:p></p><p class=MsoNormal>#define WIN32 1<o:p></o:p></p><p class=MsoNormal>#define _WIN32 1<o:p></o:p></p><p class=MsoNormal>#define _WIN32_WINNT WINVER<o:p></o:p></p><p class=MsoNormal>#define __GTHREAD_HIDE_WIN32API 1<o:p></o:p></p><p class=MsoNormal>#define __RPC_WIN32__<o:p></o:p></p><p class=MsoNormal>#define __WIN32 1<o:p></o:p></p><p class=MsoNormal>#define __WIN32__ 1 <o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So my question is why has the static analyzer stopped detecting the memory leak bug it found previously? Does anyone have any ideas or suggestions?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Thanks.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='mso-fareast-language:EN-CA'>Dennis Cote<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>