Fix #11626 FN functionConst with non-dereferenceable pointer access (#5074)

* Partial fix for #11626 FN functionConst with non-dereferenceable pointer access

* Fix #11626 FN functionConst with non-dereferenceable pointer access

* Fix test
This commit is contained in:
chrchr-github 2023-05-28 19:42:47 +02:00 committed by GitHub
parent 4c1e06a84b
commit cf4334904c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 26 deletions

View File

@ -8555,6 +8555,13 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
<container yields="end-iterator"/> <container yields="end-iterator"/>
<returnValue type="iterator" container="1"/> <returnValue type="iterator" container="1"/>
</function> </function>
<function name="std::auto_ptr::get,std::shared_ptr::get,std::unique_ptr::get,std::weak_ptr::get">
<use-retval/>
<leak-ignore/>
<noreturn>false</noreturn>
<const/>
<returnValue type="void *"/>
</function>
<memory> <memory>
<alloc init="false" buffer-size="malloc">malloc</alloc> <alloc init="false" buffer-size="malloc">malloc</alloc>
<alloc init="true" buffer-size="calloc">calloc</alloc> <alloc init="true" buffer-size="calloc">calloc</alloc>

View File

@ -2472,8 +2472,9 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
; ;
else if (var->smartPointerType() && var->smartPointerType()->classScope && isConstMemberFunc(var->smartPointerType()->classScope, end)) { else if (var->smartPointerType() && var->smartPointerType()->classScope && isConstMemberFunc(var->smartPointerType()->classScope, end)) {
; ;
} } else if (var->isSmartPointer() && Token::simpleMatch(tok1->next(), ".") && tok1->next()->originalName().empty() && mSettings->library.isFunctionConst(end)) {
else if (hasOverloadedMemberAccess(end, var->typeScope())) { ;
} else if (hasOverloadedMemberAccess(end, var->typeScope())) {
; ;
} else if (!var->typeScope() || !isConstMemberFunc(var->typeScope(), end)) } else if (!var->typeScope() || !isConstMemberFunc(var->typeScope(), end))
return false; return false;

View File

@ -36,6 +36,7 @@
#include <istream> #include <istream>
#include <iterator> #include <iterator>
#include <map> #include <map>
#include <memory>
#include <numeric> #include <numeric>
#include <string_view> #include <string_view>
#include <unordered_map> #include <unordered_map>
@ -4703,4 +4704,13 @@ void beginEnd()
std::cend(arr); std::cend(arr);
//cppcheck-suppress ignoredReturnValue //cppcheck-suppress ignoredReturnValue
std::crend(arr); std::crend(arr);
}
void smartPtr_get()
{
std::unique_ptr<int> p;
//cppcheck-suppress ignoredReturnValue
p.get();
//cppcheck-suppress nullPointer
*p = 1;
} }

View File

@ -2981,7 +2981,7 @@ private:
" return ptr.get();\n" " return ptr.get();\n"
"}\n"); "}\n");
ASSERT_EQUALS( ASSERT_EQUALS(
"[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning object that points to local variable 'ptr' that will be invalid when returning.\n", "[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning pointer to local variable 'ptr' that will be invalid when returning.\n",
errout.str()); errout.str());
} }
void danglingLifetime() { void danglingLifetime() {

View File

@ -36,31 +36,10 @@ public:
TestClass() : TestFixture("TestClass") {} TestClass() : TestFixture("TestClass") {}
private: private:
Settings settings0 = settingsBuilder().severity(Severity::style).build(); Settings settings0 = settingsBuilder().severity(Severity::style).library("std.cfg").build();
Settings settings1 = settingsBuilder().severity(Severity::warning).build(); Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build();
void run() override { void run() override {
// Load std.cfg configuration
{
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <memory>\n"
" <alloc init=\"false\">malloc</alloc>\n"
" <dealloc>free</dealloc>\n"
" </memory>\n"
" <smart-pointer class-name=\"std::shared_ptr\"/>\n"
" <container id=\"stdVector\" startPattern=\"std :: vector &lt;\" itEndPattern=\"&gt; :: const_iterator\">\n"
" <access>\n"
" <function name=\"begin\" yields=\"start-iterator\"/>\n"
" <function name=\"end\" yields=\"end-iterator\"/>\n"
" </access>\n"
" </container>\n"
"</def>";
ASSERT(settings0.library.loadxmldata(xmldata, sizeof(xmldata)));
ASSERT(settings1.library.loadxmldata(xmldata, sizeof(xmldata)));
}
TEST_CASE(virtualDestructor1); // Base class not found => no error TEST_CASE(virtualDestructor1); // Base class not found => no error
TEST_CASE(virtualDestructor2); // Base class doesn't have a destructor TEST_CASE(virtualDestructor2); // Base class doesn't have a destructor
TEST_CASE(virtualDestructor3); // Base class has a destructor, but it's not virtual TEST_CASE(virtualDestructor3); // Base class has a destructor, but it's not virtual
@ -6529,6 +6508,13 @@ private:
"[test.cpp:3]: (style, inconclusive) Technically the member function 'S::g' can be const.\n" "[test.cpp:3]: (style, inconclusive) Technically the member function 'S::g' can be const.\n"
"[test.cpp:4]: (style, inconclusive) Technically the member function 'S::h' can be const.\n", "[test.cpp:4]: (style, inconclusive) Technically the member function 'S::h' can be const.\n",
errout.str()); errout.str());
checkConst("struct S {\n"
" bool f() { return p.get() != nullptr; }\n"
" std::shared_ptr<int> p;\n"
"};\n");
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Technically the member function 'S::f' can be const.\n",
errout.str());
} }
void const89() { // #11654 void const89() { // #11654