Fixed #8816 (FP shadowLocal - variable shadows a template function?)
This commit is contained in:
parent
9ef3c79bc6
commit
a8cbbe0e16
|
@ -3005,16 +3005,18 @@ void CheckOther::checkShadowVariables()
|
||||||
continue;
|
continue;
|
||||||
if (scope.type == Scope::eFunction && scope.className == var.name())
|
if (scope.type == Scope::eFunction && scope.className == var.name())
|
||||||
continue;
|
continue;
|
||||||
shadowVariablesError(var.nameToken(), shadowed);
|
shadowError(var.nameToken(), shadowed, shadowed->varId() != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::shadowVariablesError(const Token *var, const Token *shadowed)
|
void CheckOther::shadowError(const Token *var, const Token *shadowed, bool shadowVar)
|
||||||
{
|
{
|
||||||
ErrorPath errorPath;
|
ErrorPath errorPath;
|
||||||
errorPath.push_back(ErrorPathItem(shadowed, "Shadowed declaration"));
|
errorPath.push_back(ErrorPathItem(shadowed, "Shadowed declaration"));
|
||||||
errorPath.push_back(ErrorPathItem(var, "Shadow variable"));
|
errorPath.push_back(ErrorPathItem(var, "Shadow variable"));
|
||||||
const std::string &varname = var ? var->str() : "var";
|
const std::string &varname = var ? var->str() : (shadowVar ? "var" : "f");
|
||||||
reportError(errorPath, Severity::style, "shadowLocal", "$symbol:" + varname + "\nLocal variable $symbol shadows outer symbol", CWE398, false);
|
const char *id = shadowVar ? "shadowVar" : "shadowFunction";
|
||||||
|
std::string message = "$symbol:" + varname + "\nLocal variable $symbol shadows outer " + (shadowVar ? "variable" : "function");
|
||||||
|
reportError(errorPath, Severity::style, id, message, CWE398, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@ private:
|
||||||
void accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive);
|
void accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive);
|
||||||
void funcArgNamesDifferent(const std::string & functionName, size_t index, const Token* declaration, const Token* definition);
|
void funcArgNamesDifferent(const std::string & functionName, size_t index, const Token* declaration, const Token* definition);
|
||||||
void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector<const Token*> & declarations, const std::vector<const Token*> & definitions);
|
void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector<const Token*> & declarations, const std::vector<const Token*> & definitions);
|
||||||
void shadowVariablesError(const Token *var, const Token *shadowed);
|
void shadowError(const Token *var, const Token *shadowed, bool shadowVar);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
|
||||||
CheckOther c(nullptr, settings, errorLogger);
|
CheckOther c(nullptr, settings, errorLogger);
|
||||||
|
@ -330,7 +330,8 @@ private:
|
||||||
c.accessMovedError(nullptr, "v", nullptr, false);
|
c.accessMovedError(nullptr, "v", nullptr, false);
|
||||||
c.funcArgNamesDifferent("function", 1, nullptr, nullptr);
|
c.funcArgNamesDifferent("function", 1, nullptr, nullptr);
|
||||||
c.redundantBitwiseOperationInSwitchError(nullptr, "varname");
|
c.redundantBitwiseOperationInSwitchError(nullptr, "varname");
|
||||||
c.shadowVariablesError(nullptr, nullptr);
|
c.shadowError(nullptr, nullptr, false);
|
||||||
|
c.shadowError(nullptr, nullptr, true);
|
||||||
|
|
||||||
const std::vector<const Token *> nullvec;
|
const std::vector<const Token *> nullvec;
|
||||||
c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec);
|
c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec);
|
||||||
|
|
|
@ -217,7 +217,7 @@ private:
|
||||||
TEST_CASE(funcArgOrderDifferent);
|
TEST_CASE(funcArgOrderDifferent);
|
||||||
TEST_CASE(cpp11FunctionArgInit); // #7846 - "void foo(int declaration = {}) {"
|
TEST_CASE(cpp11FunctionArgInit); // #7846 - "void foo(int declaration = {}) {"
|
||||||
|
|
||||||
TEST_CASE(shadowLocal);
|
TEST_CASE(shadowVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(const char code[], const char *filename = nullptr, bool experimental = false, bool inconclusive = true, bool runSimpleChecks=true, Settings* settings = 0) {
|
void check(const char code[], const char *filename = nullptr, bool experimental = false, bool inconclusive = true, bool runSimpleChecks=true, Settings* settings = 0) {
|
||||||
|
@ -5380,7 +5380,7 @@ private:
|
||||||
" const int a = getA + 3;\n"
|
" const int a = getA + 3;\n"
|
||||||
" return 0;\n"
|
" return 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:4]: (style) Local variable getA shadows outer symbol\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:4]: (style) Local variable getA shadows outer function\n", errout.str());
|
||||||
|
|
||||||
check("class A{public:A(){}};\n"
|
check("class A{public:A(){}};\n"
|
||||||
"const A& getA(){static A a;return a;}\n"
|
"const A& getA(){static A a;return a;}\n"
|
||||||
|
@ -7441,14 +7441,20 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void shadowLocal() {
|
void shadowVariables() {
|
||||||
check("int x;\n"
|
check("int x;\n"
|
||||||
"void f() { int x; }\n");
|
"void f() { int x; }\n");
|
||||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2]: (style) Local variable x shadows outer symbol\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2]: (style) Local variable x shadows outer variable\n", errout.str());
|
||||||
|
|
||||||
check("int x();\n"
|
check("int x();\n"
|
||||||
"void f() { int x; }\n");
|
"void f() { int x; }\n");
|
||||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2]: (style) Local variable x shadows outer symbol\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2]: (style) Local variable x shadows outer function\n", errout.str());
|
||||||
|
|
||||||
|
check("struct C {\n"
|
||||||
|
" C(int x) : x(x) {}\n" // <- we do not want a FP here
|
||||||
|
" int x;\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" if (cond) {int x;}\n" // <- not a shadow variable
|
" if (cond) {int x;}\n" // <- not a shadow variable
|
||||||
|
|
Loading…
Reference in New Issue