Dave Ohlsson - 2021-04-23

My environment:
Ubuntu 18.04
Cppcheck 2.4.1
* I use options --library=microsoft_atl and --library=windows

The comments in the file below explain my problem.

How can I get rid of "returnDanglingLifetime" in foo3()?

I created file /usr/local/cppcheck/cfg/my_own_atl.cfg:

<?xml version ="1.0"?>
<def>
  <type-checks>
    <returnDanglingLifetime>
       <suppress>CComBSTR</suppress>
    </returnDanglingLifetime>
  </type-checks>
</def>

and I added option '--library=my_own_atl', but that did not help.

Here is the file:

#include <QString>
#include <string>
#include <atlcomcli.h>
// atlcomcli.h is in directory
// C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\atlmfc\include

std::string foo1()
{
    QString qtString("This is a Qt String.");
    std::string stdString = qtString.toStdString().c_str();
    // Cppcheck generates no "returnDanglingLifetime" error.
    //
    // This is correct, because the constructor of std::string copies
    // the C string returned by c_str().
    return stdString;
}

const char* foo2()
{
    QString qtString("This is a Qt String.");
    const char* rawString = qtString.toStdString().c_str();
    // Cppcheck generates this error:
    // id="returnDanglingLifetime"
    // severity="error" msg="Returning pointer that will be invalid
    // when returning."
    // verbose="Returning pointer that will be invalid when returning."
    // cwe="562"
    //
    // This is correct: 'rawString' no longer exists past the previous
    // statement.
    return rawString;
}

CComBSTR foo3()
{
    QString qtString("This is a Qt String.");
    CComBSTR comString = qtString.toStdString().c_str();
    // Cppcheck generates this error:
    // id="returnDanglingLifetime"
    // severity="error" msg="Returning pointer that will be invalid
    // when returning."
    // verbose="Returning pointer that will be invalid when returning."
    // cwe="562"
    //
    // ### This is NOT correct: ###
    // CComBSTR is a string class, similar to std::string. The
    // constructor of CComBSTR copies its C string argument, just
    // like std::string.
    return comString;
}