From dad64bfcc8ca501b523e982cb817eba0c558266a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 2 Feb 2022 19:30:49 +0100 Subject: [PATCH] Fix #10091 FP shadowFunction with default destructor implementation / Tests for #8635, #9776, #9940, #9951, #10018 (#3763) --- lib/symboldatabase.cpp | 2 +- test/cfg/posix.c | 9 +++++++++ test/test64bit.cpp | 9 +++++++++ test/testincompletestatement.cpp | 3 +++ test/testleakautovar.cpp | 14 ++++++++++++-- test/testnullpointer.cpp | 10 ++++++++++ test/testother.cpp | 9 +++++++++ 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4794d2ea1..b9b1f5077 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -639,7 +639,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // function prototype? else if (declEnd && declEnd->str() == ";") { - if (tok->previous() && tok->previous()->str() == "::" && + if (tok->astParent() && tok->astParent()->str() == "::" && Token::Match(declEnd->previous(), "default|delete")) { addClassFunction(&scope, &tok, argStart); continue; diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 71dd978ed..b6461fd76 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -268,6 +268,15 @@ void * memleak_mmap2() // #8327 return NULL; } +void * identicalCondition_mmap(int fd, size_t size) // #9940 +{ + void* buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buffer == MAP_FAILED) { + return NULL; + } + return buffer; +} + void resourceLeak_fdopen(int fd) { // cppcheck-suppress unreadVariable diff --git a/test/test64bit.cpp b/test/test64bit.cpp index df4501fff..55a9d7771 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -144,6 +144,15 @@ private: " Array a = f();\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("struct S {\n" // #9951 + " enum E { E0 };\n" + " std::array g(S::E);\n" + "};\n" + "void f() {\n" + " std::array a = S::g(S::E::E0);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void structmember() { diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 8a37bf932..b59994045 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -381,6 +381,9 @@ private: check("void f1(int x) { x; }", true); ASSERT_EQUALS("[test.cpp:1]: (warning) Unused variable value 'x'\n", errout.str()); + check("void f() { if (Type t; g(t)) {} }"); // #9776 + ASSERT_EQUALS("", errout.str()); + } void vardecl() { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 3e4952a60..ec1cf65b1 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -708,13 +708,23 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Dereferencing 'ptr' after it is deallocated / released\n", errout.str()); } - void deallocuse9() { // #9781 - check("void f(Type* p) {\n" + void deallocuse9() { + check("void f(Type* p) {\n" // #9781 " std::shared_ptr sp(p);\n" " bool b = p->foo();\n" " return b;\n" "}\n", /*cpp*/ true); ASSERT_EQUALS("", errout.str()); + + check("struct A {\n" // #8635 + " std::vector> array_;\n" + " A* foo() {\n" + " A* a = new A();\n" + " array_.push_back(std::unique_ptr(a));\n" + " return a;\n" + " }\n" + "};\n", /*cpp*/ true); + ASSERT_EQUALS("", errout.str()); } void doublefree1() { // #3895 diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 9a8363394..a01a34de3 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2693,6 +2693,16 @@ private: " if (addr == &x->y.z[0]) {}\n" "}"); ASSERT_EQUALS("", errout.str()); + + checkP("typedef int Count;\n" // #10018 + "#define offsetof(TYPE, MEMBER) ((Count) & ((TYPE*)0)->MEMBER)\n" + "struct S {\n" + " int a[20];\n" + "};\n" + "int g(int i) {\n" + " return offsetof(S, a[i]);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void nullpointerSwitch() { // #2626 diff --git a/test/testother.cpp b/test/testother.cpp index 5badbe7aa..0acbdfcc2 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -9336,6 +9336,15 @@ private: check("class C { C(); void foo() { static int C = 0; } }"); // #9195 - shadow constructor ASSERT_EQUALS("", errout.str()); + check("struct C {\n" // #10091 - shadow destructor + " ~C();\n" + " void f() {\n" + " bool C{};\n" + " }\n" + "};\n" + "C::~C() = default;"); + ASSERT_EQUALS("", errout.str()); + // 10752 - no check("struct S {\n" " int i;\n"