Fix 11992: FN (regression): uninitvar (#5465)
This commit is contained in:
parent
3089fc393b
commit
58a7519cbb
|
@ -2809,6 +2809,11 @@ bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp,
|
|||
return false;
|
||||
if (Token::Match(start, "; %varid% =", var->declarationId()))
|
||||
start = start->tokAt(2);
|
||||
if (Token::simpleMatch(start, "=")) {
|
||||
const Token* next = nextAfterAstRightmostLeafGeneric(start);
|
||||
if (next)
|
||||
start = next;
|
||||
}
|
||||
return isExpressionChanged(var->nameToken(), start->next(), var->scope()->bodyEnd, settings, cpp, depth);
|
||||
}
|
||||
|
||||
|
|
|
@ -231,9 +231,12 @@ private:
|
|||
" if (b) { (int)((INTOF(8))result >> b); }\n"
|
||||
"}", "if", "}");
|
||||
// #9235
|
||||
ASSERT_EQUALS(true, isVariableChanged("void f() {\n"
|
||||
" int &a = a;\n"
|
||||
"}\n", "= a", "}"));
|
||||
ASSERT_EQUALS(false,
|
||||
isVariableChanged("void f() {\n"
|
||||
" int &a = a;\n"
|
||||
"}\n",
|
||||
"= a",
|
||||
"}"));
|
||||
|
||||
ASSERT_EQUALS(false, isVariableChanged("void f(const A& a) { a.f(); }", "{", "}"));
|
||||
ASSERT_EQUALS(true,
|
||||
|
|
|
@ -2653,9 +2653,9 @@ private:
|
|||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const T& z = x;\n" //Make sure we find all assignments
|
||||
" T& y = x\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" const T& z = x;\n" // Make sure we find all assignments
|
||||
" T& y = x;\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
|
@ -2667,29 +2667,29 @@ private:
|
|||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = x\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" U& y = x;\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" my<fancy>::type& y = x\n" //we don't know if y is const or not
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" my<fancy>::type& y = x;\n" // we don't know if y is const or not
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = static_cast<const U&>(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" const U& y = static_cast<const U&>(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = static_cast<U&>(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" U& y = static_cast<U&>(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
|
@ -2698,129 +2698,127 @@ private:
|
|||
" const U& y = dynamic_cast<const U&>(x)\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check(
|
||||
"struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = dynamic_cast<U const &>(x)\n"
|
||||
"}"
|
||||
);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = dynamic_cast<U & const>(x)\n"
|
||||
" const U& y = dynamic_cast<U const &>(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = dynamic_cast<U&>(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" const U& y = dynamic_cast<U & const>(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = dynamic_cast<U&>(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = dynamic_cast<typename const U&>(x)\n"
|
||||
" const U& y = dynamic_cast<typename const U&>(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = dynamic_cast<typename U&>(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" U& y = dynamic_cast<typename U&>(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U* y = dynamic_cast<U*>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" U* y = dynamic_cast<U*>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U * y = dynamic_cast<const U *>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" const U * y = dynamic_cast<const U *>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U const * y = dynamic_cast<U const *>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" U const * y = dynamic_cast<U const *>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U * const y = dynamic_cast<U * const>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" U * const y = dynamic_cast<U * const>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U const * const * const * const y = dynamic_cast<const U const * const * const * const>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" const U const * const * const * const y = dynamic_cast<const U const * const * const * const>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U const * const * * const y = dynamic_cast<const U const * const * * const>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" const U const * const * * const y = dynamic_cast<const U const * const * * const>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" my::fancy<typename type const *> const * * const y = dynamic_cast<my::fancy<typename type const *> const * * const>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" my::fancy<typename type const *> const * * const y = dynamic_cast<my::fancy<typename type const *> const * * const>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" my::fancy<typename type const *> const * const * const y = dynamic_cast<my::fancy<typename type const *> const * const * const>(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" my::fancy<typename type const *> const * const * const y = dynamic_cast<my::fancy<typename type const *> const * const * const>(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = (const U&)(x)\n"
|
||||
" const U& y = (const U&)(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = (U&)(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" U& y = (U&)(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" const U& y = (typename const U&)(x)\n"
|
||||
" const U& y = (typename const U&)(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U& y = (typename U&)(x)\n"
|
||||
" y.mutate();\n" //to avoid warnings that y can be const
|
||||
" U& y = (typename U&)(x);\n"
|
||||
" y.mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct T : public U { void dostuff() const {}};\n"
|
||||
"void a(T& x) {\n"
|
||||
" x.dostuff();\n"
|
||||
" U* y = (U*)(&x)\n"
|
||||
" y->mutate();\n" //to avoid warnings that y can be const
|
||||
" U* y = (U*)(&x);\n"
|
||||
" y->mutate();\n" // to avoid warnings that y can be const
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) C-style pointer casting\n", errout.str());
|
||||
|
||||
|
|
|
@ -6224,6 +6224,19 @@ private:
|
|||
" int* a[] = { &x };\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #11992
|
||||
valueFlowUninit("void foo(const int &x) {\n"
|
||||
" if(x==42) {;}\n"
|
||||
"}\n"
|
||||
"void test(void) {\n"
|
||||
" int t;\n"
|
||||
" int &p = t;\n"
|
||||
" int &s = p;\n"
|
||||
" int &q = s;\n"
|
||||
" foo(q);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: q\n", errout.str());
|
||||
}
|
||||
|
||||
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value
|
||||
|
|
Loading…
Reference in New Issue