Handle (&foo)-> in isVariableChanged (#3624)
This commit is contained in:
parent
d5daba331f
commit
af289c8357
|
@ -2134,11 +2134,14 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
||||||
int derefs = 0;
|
int derefs = 0;
|
||||||
while (Token::simpleMatch(tok2->astParent(), "*") ||
|
while (Token::simpleMatch(tok2->astParent(), "*") ||
|
||||||
(Token::simpleMatch(tok2->astParent(), ".") && !Token::simpleMatch(tok2->astParent()->astParent(), "(")) ||
|
(Token::simpleMatch(tok2->astParent(), ".") && !Token::simpleMatch(tok2->astParent()->astParent(), "(")) ||
|
||||||
|
(tok2->astParent() && tok2->astParent()->isUnaryOp("&") && !tok2->astParent()->astOperand2() && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->") ||
|
||||||
(Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) {
|
(Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) {
|
||||||
if (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->"))
|
if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->")))
|
||||||
derefs++;
|
derefs++;
|
||||||
if (derefs > indirect)
|
if (derefs > indirect)
|
||||||
break;
|
break;
|
||||||
|
if ((tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->"))
|
||||||
|
tok2 = tok2->astParent();
|
||||||
tok2 = tok2->astParent();
|
tok2 = tok2->astParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(isVariableUsageDeref); // *p
|
TEST_CASE(isVariableUsageDeref); // *p
|
||||||
|
|
||||||
|
TEST_CASE(uninitvar_memberaccess); // (&(a))->b <=> a.b
|
||||||
|
|
||||||
// whole program analysis
|
// whole program analysis
|
||||||
TEST_CASE(ctuTest);
|
TEST_CASE(ctuTest);
|
||||||
}
|
}
|
||||||
|
@ -5989,6 +5991,24 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uninitvar_memberaccess() {
|
||||||
|
valueFlowUninit("struct foo{char *bar;};\n"
|
||||||
|
"void f(unsigned long long *p) {\n"
|
||||||
|
" foo a;\n"
|
||||||
|
" ((&a)->bar) = reinterpret_cast<char*>(*p);\n"
|
||||||
|
" if ((&a)->bar) ;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
valueFlowUninit("struct foo{char *bar;};\n"
|
||||||
|
"void f(unsigned long long *p) {\n"
|
||||||
|
" foo a;\n"
|
||||||
|
" ((&(a))->bar) = reinterpret_cast<char*>(*p);\n"
|
||||||
|
" if ((&a)->bar) ;\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[]) {
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
Loading…
Reference in New Issue