parent
a7d487f6db
commit
720ae01898
|
@ -3295,6 +3295,12 @@ struct MemberExpressionAnalyzer : SubExpressionAnalyzer {
|
||||||
: SubExpressionAnalyzer(e, std::move(val), t, s), varname(std::move(varname))
|
: SubExpressionAnalyzer(e, std::move(val), t, s), varname(std::move(varname))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool match(const Token* tok) const override
|
||||||
|
{
|
||||||
|
return SubExpressionAnalyzer::match(tok) ||
|
||||||
|
(Token::simpleMatch(tok->astParent(), ".") && SubExpressionAnalyzer::match(tok->astParent()));
|
||||||
|
}
|
||||||
|
|
||||||
bool submatch(const Token* tok, bool exact) const override
|
bool submatch(const Token* tok, bool exact) const override
|
||||||
{
|
{
|
||||||
if (!Token::Match(tok, ". %var%"))
|
if (!Token::Match(tok, ". %var%"))
|
||||||
|
@ -7965,6 +7971,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
|
||||||
Token* start = findStartToken(var, tok->next(), &settings->library);
|
Token* start = findStartToken(var, tok->next(), &settings->library);
|
||||||
|
|
||||||
std::map<Token*, ValueFlow::Value> partialReads;
|
std::map<Token*, ValueFlow::Value> partialReads;
|
||||||
|
Analyzer::Result result;
|
||||||
if (const Scope* scope = var->typeScope()) {
|
if (const Scope* scope = var->typeScope()) {
|
||||||
if (Token::findsimplematch(scope->bodyStart, "union", scope->bodyEnd))
|
if (Token::findsimplematch(scope->bodyStart, "union", scope->bodyEnd))
|
||||||
continue;
|
continue;
|
||||||
|
@ -7979,7 +7986,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings);
|
MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings);
|
||||||
valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings);
|
result = valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings);
|
||||||
|
|
||||||
for (auto&& p : *analyzer.partialReads) {
|
for (auto&& p : *analyzer.partialReads) {
|
||||||
Token* tok2 = p.first;
|
Token* tok2 = p.first;
|
||||||
|
@ -8009,6 +8016,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
|
||||||
if (partial)
|
if (partial)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (result.terminate != Analyzer::Terminate::Modified)
|
||||||
valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings);
|
valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6181,7 +6181,7 @@ private:
|
||||||
" memcpy(wcsin, x, sizeof(wcsstruct));\n" // <- warning
|
" memcpy(wcsin, x, sizeof(wcsstruct));\n" // <- warning
|
||||||
" x->wcsprm = NULL;\n" // <- no warning
|
" x->wcsprm = NULL;\n" // <- no warning
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: x.wcsprm\n", errout.str());
|
||||||
|
|
||||||
valueFlowUninit("struct wcsstruct {\n"
|
valueFlowUninit("struct wcsstruct {\n"
|
||||||
" int *wcsprm;\n"
|
" int *wcsprm;\n"
|
||||||
|
@ -6264,7 +6264,7 @@ private:
|
||||||
" int * x = &s1.x;\n"
|
" int * x = &s1.x;\n"
|
||||||
" struct S s2 = {*x, 0};\n"
|
" struct S s2 = {*x, 0};\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());
|
||||||
|
|
||||||
valueFlowUninit("struct S {\n"
|
valueFlowUninit("struct S {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
@ -6277,7 +6277,7 @@ private:
|
||||||
" int * x = &s1.x;\n"
|
" int * x = &s1.x;\n"
|
||||||
" s2.x = *x;\n"
|
" s2.x = *x;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str());
|
||||||
|
|
||||||
valueFlowUninit("void f(bool * x) {\n"
|
valueFlowUninit("void f(bool * x) {\n"
|
||||||
" *x = false;\n"
|
" *x = false;\n"
|
||||||
|
@ -6897,7 +6897,7 @@ private:
|
||||||
" int a = ab.a;\n"
|
" int a = ab.a;\n"
|
||||||
" int b = ab.b;\n"
|
" int b = ab.b;\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab.b\n", "", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab.b\n", errout.str());
|
||||||
|
|
||||||
// STL class member
|
// STL class member
|
||||||
valueFlowUninit("struct A {\n"
|
valueFlowUninit("struct A {\n"
|
||||||
|
@ -7009,7 +7009,7 @@ private:
|
||||||
" memcpy(in, s, sizeof(S));\n"
|
" memcpy(in, s, sizeof(S));\n"
|
||||||
" s->p = NULL;\n"
|
" s->p = NULL;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n",
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s.p\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
valueFlowUninit("struct S {\n" // #11321
|
valueFlowUninit("struct S {\n" // #11321
|
||||||
|
@ -7270,7 +7270,7 @@ private:
|
||||||
" A::B b;\n"
|
" A::B b;\n"
|
||||||
" x.push_back(b);\n"
|
" x.push_back(b);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: b\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: b.i\n", errout.str());
|
||||||
|
|
||||||
valueFlowUninit("struct A {\n"
|
valueFlowUninit("struct A {\n"
|
||||||
" struct B {\n"
|
" struct B {\n"
|
||||||
|
@ -7294,7 +7294,7 @@ private:
|
||||||
" A a;\n"
|
" A a;\n"
|
||||||
" x.push_back(a);\n"
|
" x.push_back(a);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: a.j\n", errout.str());
|
||||||
|
|
||||||
valueFlowUninit("struct S { struct T { int* p; } t[2]; };\n" // #11018
|
valueFlowUninit("struct S { struct T { int* p; } t[2]; };\n" // #11018
|
||||||
"void f() {\n"
|
"void f() {\n"
|
||||||
|
@ -7314,6 +7314,15 @@ private:
|
||||||
" int y = x < (1, s.i);\n"
|
" int y = x < (1, s.i);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s.i\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s.i\n", errout.str());
|
||||||
|
|
||||||
|
valueFlowUninit("struct S { int x; };\n" // #11353
|
||||||
|
"struct S f() {\n"
|
||||||
|
" struct S s;\n"
|
||||||
|
" int* p = &s.x;\n"
|
||||||
|
" *p = 0;\n"
|
||||||
|
" return s;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctu_(const char* file, int line, const char code[]) {
|
void ctu_(const char* file, int line, const char code[]) {
|
||||||
|
|
Loading…
Reference in New Issue