Merge branch 'main' of https://github.com/danmar/cppcheck into main

This commit is contained in:
orbitcowboy 2020-12-26 13:46:35 +01:00
commit ef2746d2e1
5 changed files with 50 additions and 15 deletions

View File

@ -47,6 +47,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wno-missing-braces)
add_compile_options(-Wno-unused-function)
add_compile_options_safe(-Wextra-semi-stmt)
add_compile_options_safe(-Wcomma)
if(ENABLE_COVERAGE OR ENABLE_COVERAGE_XML)
message(FATAL_ERROR "Do not use clang for generate code coverage. Use gcc.")

View File

@ -198,7 +198,7 @@ static std::string str(ExprEngine::ValuePtr val)
case ExprEngine::ValueType::BailoutValue:
typestr = "BailoutValue";
break;
};
}
std::ostringstream ret;
ret << val->name << "=" << typestr << "(" << val->getRange() << ")";
@ -2520,7 +2520,7 @@ static std::string execute(const Token *start, const Token *end, Data &data)
// This is intended for testing
throw ExprEngineException(tok, "__CPPCHECK_BAILOUT__");
if (Token::simpleMatch(tok, "while (") && (tok->linkAt(1), ") ;") && tok->next()->astOperand1()->hasKnownIntValue() && tok->next()->astOperand1()->getKnownIntValue() == 0) {
if (Token::simpleMatch(tok, "while (") && Token::simpleMatch(tok->linkAt(1), ") ;") && tok->next()->astOperand1()->hasKnownIntValue() && tok->next()->astOperand1()->getKnownIntValue() == 0) {
tok = tok->tokAt(4);
continue;
}

View File

@ -1696,8 +1696,10 @@ void Tokenizer::simplifyTypedef()
namespace {
struct ScopeInfo3 {
ScopeInfo3(const std::string &name_, const Token *bodyEnd_) : name(name_), bodyEnd(bodyEnd_) {}
ScopeInfo3(const std::string &name_, const Token *bodyStart_, const Token *bodyEnd_)
: name(name_), bodyStart(bodyStart_), bodyEnd(bodyEnd_) {}
const std::string name;
const Token * const bodyStart;
const Token * const bodyEnd;
std::set<std::string> usingNamespaces;
};
@ -1716,6 +1718,9 @@ namespace {
{
if (!tok)
return;
if (tok->str() == "{" && !scopeInfo->empty() && tok == scopeInfo->back().bodyStart)
return;
while (tok->str() == "}" && !scopeInfo->empty() && tok == scopeInfo->back().bodyEnd)
scopeInfo->pop_back();
if (!Token::Match(tok, "namespace|class|struct|union %name% {|:|::|<")) {
@ -1762,13 +1767,13 @@ namespace {
scope = tok1->strAt(-3) + " :: " + scope;
tok1 = tok1->tokAt(-2);
}
scopeInfo->emplace_back(scope, tok->link());
scopeInfo->emplace_back(scope, tok, tok->link());
added = true;
}
}
if (all && !added)
scopeInfo->emplace_back("", tok->link());
scopeInfo->emplace_back("", tok, tok->link());
}
return;
}
@ -1791,7 +1796,7 @@ namespace {
tok = tok->next();
}
if (tok && tok->str() == "{") {
scopeInfo->emplace_back(classname,tok->link());
scopeInfo->emplace_back(classname, tok, tok->link());
}
}
@ -1878,14 +1883,16 @@ namespace {
return true;
// check using namespace
if (!scopeList1.back().usingNamespaces.empty()) {
if (qualification.empty()) {
if (scopeList1.back().usingNamespaces.find(scope) != scopeList1.back().usingNamespaces.end())
return true;
} else {
for (auto ns : scopeList1.back().usingNamespaces) {
if (scope == ns + " :: " + qualification)
for (std::list<ScopeInfo3>::const_reverse_iterator it = scopeList1.crbegin(); it != scopeList1.crend(); ++it) {
if (!it->usingNamespaces.empty()) {
if (qualification.empty()) {
if (it->usingNamespaces.find(scope) != it->usingNamespaces.end())
return true;
} else {
for (auto ns : it->usingNamespaces) {
if (scope == ns + " :: " + qualification)
return true;
}
}
}
}
@ -1945,7 +1952,7 @@ bool Tokenizer::simplifyUsing()
};
std::list<Using> usingList;
scopeList.emplace_back("", nullptr);
scopeList.emplace_back("", nullptr, nullptr);
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (mErrorLogger && !list.getFiles().empty())
@ -1975,7 +1982,7 @@ bool Tokenizer::simplifyUsing()
continue;
std::list<ScopeInfo3> scopeList1;
scopeList1.emplace_back("", nullptr);
scopeList1.emplace_back("", nullptr, nullptr);
std::string name = tok->strAt(1);
const Token *nameToken = tok->next();
std::string scope = getScopeName(scopeList);

View File

@ -75,6 +75,7 @@ private:
TEST_CASE(simplifyUsing9388);
TEST_CASE(simplifyUsing9518);
TEST_CASE(simplifyUsing9757);
TEST_CASE(simplifyUsing10008);
}
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
@ -647,6 +648,21 @@ private:
"switch ( type ) { } }";
ASSERT_EQUALS(exp, tok(code, false));
}
void simplifyUsing10008() {
const char code[] = "namespace ns {\n"
" using ArrayType = std::vector<int>;\n"
"}\n"
"using namespace ns;\n"
"static void f() {\n"
" const ArrayType arr;\n"
"}";
const char exp[] = "using namespace ns ; "
"static void f ( ) { "
"const std :: vector < int > arr ; "
"}";
ASSERT_EQUALS(exp, tok(code, false));
}
};
REGISTER_TEST(TestSimplifyUsing)

View File

@ -4741,6 +4741,17 @@ private:
"}\n",
true);
ASSERT_EQUALS("", errout.str());
check("namespace ns {\n"
" using ArrayType = std::vector<int>;\n"
"}\n"
"using namespace ns;\n"
"static void f() {\n"
" const ArrayType arr;\n"
" for (const auto &a : arr) {}\n"
"}",
true);
ASSERT_EQUALS("[test.cpp:7]: (style) Iterating over container 'arr' that is always empty.\n", errout.str());
}
void checkMutexes() {