Fix #8541 FP variableScope (std::for_each with lambda) (#3924)

This commit is contained in:
chrchr-github 2022-03-22 21:50:46 +01:00 committed by GitHub
parent e48b5fc920
commit 39567ea8c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 3 deletions

View File

@ -572,7 +572,7 @@ $(libcppdir)/token.o: lib/token.cpp lib/astutils.h lib/config.h lib/errortypes.h
$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/tokenize.o $(libcppdir)/tokenize.cpp
$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/tokenlist.o $(libcppdir)/tokenlist.cpp
$(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h
@ -605,7 +605,7 @@ test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/color.h li
test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testassert.o test/testassert.cpp
test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testastutils.o test/testastutils.cpp
test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h

View File

@ -1929,6 +1929,19 @@ bool isReturnScope(const Token* const endToken, const Library* library, const To
return false;
}
bool isWithinScope(const Token* tok, const Variable* var, Scope::ScopeType type)
{
if (!tok || !var)
return false;
const Scope* scope = tok->scope();
while (scope && scope != var->scope()) {
if (scope->type == type)
return true;
scope = scope->nestedIn;
}
return false;
}
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings *settings, bool *inconclusive)
{
if (!tok)

View File

@ -30,6 +30,7 @@
#include "config.h"
#include "errortypes.h"
#include "symboldatabase.h"
class Function;
class Library;
@ -238,6 +239,11 @@ bool isReturnScope(const Token* const endToken,
const Token** unknownFunc = nullptr,
bool functionScope = false);
/** Is tok within a scope of the given type, nested within var's scope? */
bool isWithinScope(const Token* tok,
const Variable* var,
Scope::ScopeType type);
/// Return the token to the function and the argument number
const Token * getTokenArgumentFunction(const Token * tok, int& argn);
Token* getTokenArgumentFunction(Token* tok, int& argn);

View File

@ -958,7 +958,7 @@ void CheckOther::checkVariableScope()
bool reduce = true;
bool used = false; // Don't warn about unused variables
for (; tok && tok != var->scope()->bodyEnd; tok = tok->next()) {
if (tok->str() == "{" && tok->scope() != tok->previous()->scope() && !tok->isExpandedMacro() && tok->scope()->type != Scope::eLambda) {
if (tok->str() == "{" && tok->scope() != tok->previous()->scope() && !tok->isExpandedMacro() && !isWithinScope(tok, var, Scope::ScopeType::eLambda)) {
if (used) {
bool used2 = false;
if (!checkInnerScope(tok, var, used2) || used2) {

View File

@ -97,6 +97,7 @@ private:
TEST_CASE(varScope27); // #7733 - #if
TEST_CASE(varScope28); // #10527
TEST_CASE(varScope29); // #10888
TEST_CASE(varScope30); // #8541
TEST_CASE(oldStylePointerCast);
TEST_CASE(invalidPointerCast);
@ -1347,6 +1348,22 @@ private:
ASSERT_EQUALS("[test.cpp:2]: (style) The scope of the variable 's' can be reduced.\n", errout.str());
}
void varScope30() { // #8541
check("bool f(std::vector<int>& v, int i) {\n"
" int n = 0;\n"
" bool b = false;\n"
" std::for_each(v.begin(), v.end(), [&](int j) {\n"
" if (j == i) {\n"
" ++n;\n"
" if (n > 5)\n"
" b = true;\n"
" }\n"
" });\n"
" return b;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
#define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__)
void checkOldStylePointerCast_(const char code[], const char* file, int line) {
// Clear the error buffer..