Fixed #5301 (False positive: (error) Division by zero - variables read from input stream)

This commit is contained in:
Daniel Marjamäki 2014-02-22 12:09:54 +01:00
parent 6273a270c7
commit 34730f623a
4 changed files with 26 additions and 1 deletions

View File

@ -6758,7 +6758,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
if (isCPP() && Token::Match(tok3, (">> " + structname + " %varid%").c_str(), varid)) { if (isCPP() && Token::Match(tok3, (">> " + structname + " %varid%").c_str(), varid)) {
// bailout for such code: ; std :: cin >> i ; // bailout for such code: ; std :: cin >> i ;
const Token *prev = tok3->previous(); const Token *prev = tok3->previous();
while (prev && prev->str() != "return" && (prev->isName() || prev->str() == "::")) while (prev && prev->str() != "return" && Token::Match(prev, "%var%|::|*"))
prev = prev->previous(); prev = prev->previous();
if (Token::Match(prev, ";|{|}|>>")) if (Token::Match(prev, ";|{|}|>>"))
break; break;

View File

@ -564,6 +564,18 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
break; break;
} }
// bailout: possible assignment using >>
if (Token::Match(tok2->previous(), ">> %var% >>|;")) {
const Token *parent = tok2->previous();
while (Token::simpleMatch(parent,">>"))
parent = parent->astParent();
if (!parent) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "Possible assignment of " + tok2->str() + " using >>");
break;
}
}
// skip if variable is conditionally used in ?: expression // skip if variable is conditionally used in ?: expression
if (const Token *parent = skipValueInConditionalExpression(tok2)) { if (const Token *parent = skipValueInConditionalExpression(tok2)) {
if (settings->debugwarnings) if (settings->debugwarnings)

View File

@ -188,6 +188,7 @@ private:
TEST_CASE(simplifyKnownVariables53); // references TEST_CASE(simplifyKnownVariables53); // references
TEST_CASE(simplifyKnownVariables54); // #4913 'x' is not 0 after *--x=0; TEST_CASE(simplifyKnownVariables54); // #4913 'x' is not 0 after *--x=0;
TEST_CASE(simplifyKnownVariables55); // pointer alias TEST_CASE(simplifyKnownVariables55); // pointer alias
TEST_CASE(simplifyKnownVariables56); // ticket #5301 - >>
TEST_CASE(simplifyKnownVariablesIfEq1); // if (a==5) => a is 5 in the block TEST_CASE(simplifyKnownVariablesIfEq1); // if (a==5) => a is 5 in the block
TEST_CASE(simplifyKnownVariablesIfEq2); // if (a==5) { buf[a++] = 0; } TEST_CASE(simplifyKnownVariablesIfEq2); // if (a==5) { buf[a++] = 0; }
TEST_CASE(simplifyKnownVariablesIfEq3); // #4708 - if (a==5) { buf[--a] = 0; } TEST_CASE(simplifyKnownVariablesIfEq3); // #4708 - if (a==5) { buf[--a] = 0; }
@ -2888,6 +2889,11 @@ private:
ASSERT_EQUALS("void f ( ) { int a ; if ( x > a ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (x>*p) {} }", true)); ASSERT_EQUALS("void f ( ) { int a ; if ( x > a ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (x>*p) {} }", true));
} }
void simplifyKnownVariables56() { // ticket #5301 - >>
ASSERT_EQUALS("void f ( ) { int a ; a = 0 ; int b ; b = 0 ; * p >> a >> b ; return a / b ; }",
tokenizeAndStringify("void f() { int a=0,b=0; *p>>a>>b; return a/b; }", true));
}
void simplifyKnownVariablesIfEq1() { void simplifyKnownVariablesIfEq1() {
const char code[] = "void f(int x) {\n" const char code[] = "void f(int x) {\n"
" if (x==5) {\n" " if (x==5) {\n"

View File

@ -498,6 +498,13 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 2)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 2));
code = "void f() {\n"
" static int x = 2;\n"
" a >> x;\n"
" return x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 2));
// function // function
code = "void f() {\n" code = "void f() {\n"
" char *x = 0;\n" " char *x = 0;\n"