Handle (&foo)-> in isVariableChanged (#3624)

This commit is contained in:
KenPatrickLehrmann 2022-01-02 08:14:10 +01:00 committed by GitHub
parent d5daba331f
commit af289c8357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -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();
} }

View File

@ -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("");