Fix issue 8775: Dont follow aliased variables (#1390)

This commit is contained in:
Paul Fultz II 2018-09-23 23:37:47 -05:00 committed by Daniel Marjamäki
parent d08b39c915
commit 5bebeec224
2 changed files with 22 additions and 0 deletions

View File

@ -158,6 +158,15 @@ static bool precedes(const Token * tok1, const Token * tok2)
return tok1->progressValue() < tok2->progressValue(); return tok1->progressValue() < tok2->progressValue();
} }
static bool isAliased(const Token * startTok, const Token * endTok, unsigned int varid)
{
for (const Token *tok = startTok; tok != endTok; tok = tok->next()) {
if (Token::Match(tok, "= & %varid% ;", varid))
return true;
}
return false;
}
/// This takes a token that refers to a variable and it will return the token /// This takes a token that refers to a variable and it will return the token
/// to the expression that the variable is assigned to. If its not valid to /// to the expression that the variable is assigned to. If its not valid to
/// make such substitution then it will return the original token. /// make such substitution then it will return the original token.
@ -197,6 +206,8 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok;
if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp))) if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp)))
return tok; return tok;
if (precedes(varTok, endToken) && isAliased(varTok, endToken, tok->varId()))
return tok;
// Start at beginning of initialization // Start at beginning of initialization
const Token * startToken = varTok; const Token * startToken = varTok;
while (Token::Match(startToken, "%op%|.|(|{") && startToken->astOperand1()) while (Token::Match(startToken, "%op%|.|(|{") && startToken->astOperand1())
@ -223,6 +234,8 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
return tok; return tok;
if (!var2->isConst() && (!precedes(tok2, endToken2) || isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp))) if (!var2->isConst() && (!precedes(tok2, endToken2) || isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp)))
return tok; return tok;
if (precedes(tok2, endToken2) && isAliased(tok2, endToken2, tok2->varId()))
return tok;
// Recognized as a variable but the declaration is unknown // Recognized as a variable but the declaration is unknown
} else if (tok2->varId() > 0) { } else if (tok2->varId() > 0) {
return tok; return tok;

View File

@ -4080,6 +4080,15 @@ private:
check("volatile const int var = 42;\n" check("volatile const int var = 42;\n"
"void f() { if(var == 42) {} }\n"); "void f() { if(var == 42) {} }\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int a = 0;\n"
" struct b c;\n"
" c.a = &a;\n"
" g(&c);\n"
" if (a == 0) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void duplicateExpressionLoop() { void duplicateExpressionLoop() {