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;
|
||||
while (Token::simpleMatch(tok2->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())) {
|
||||
if (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->"))
|
||||
if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->")))
|
||||
derefs++;
|
||||
if (derefs > indirect)
|
||||
break;
|
||||
if ((tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->"))
|
||||
tok2 = tok2->astParent();
|
||||
tok2 = tok2->astParent();
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
|
||||
TEST_CASE(isVariableUsageDeref); // *p
|
||||
|
||||
TEST_CASE(uninitvar_memberaccess); // (&(a))->b <=> a.b
|
||||
|
||||
// whole program analysis
|
||||
TEST_CASE(ctuTest);
|
||||
}
|
||||
|
@ -5989,6 +5991,24 @@ private:
|
|||
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[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
|
Loading…
Reference in New Issue