value flow: improved bailouts in ?:
This commit is contained in:
parent
7cfa4c8654
commit
1e3c43e708
|
@ -50,7 +50,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
||||||
unsigned int varid;
|
unsigned int varid;
|
||||||
MathLib::bigint num;
|
MathLib::bigint num;
|
||||||
const Variable *var;
|
const Variable *var;
|
||||||
if (Token::Match(tok, "==|!=|>=|<=") && tok->astOperand1() && tok->astOperand2()) {
|
if (tok->isComparisonOp() && tok->astOperand1() && tok->astOperand2()) {
|
||||||
if (tok->astOperand1()->isName() && tok->astOperand2()->isNumber()) {
|
if (tok->astOperand1()->isName() && tok->astOperand2()->isNumber()) {
|
||||||
varid = tok->astOperand1()->varId();
|
varid = tok->astOperand1()->varId();
|
||||||
var = tok->astOperand1()->variable();
|
var = tok->astOperand1()->variable();
|
||||||
|
@ -62,11 +62,6 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Token::Match(tok->astParent(), "[?:]")) {
|
|
||||||
if (settings->debugwarnings)
|
|
||||||
bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + " stopping on " + tok->astParent()->str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (Token::Match(tok->previous(), "if|while ( %var% %oror%|&&|)") ||
|
} else if (Token::Match(tok->previous(), "if|while ( %var% %oror%|&&|)") ||
|
||||||
Token::Match(tok, "%oror%|&& %var% %oror%|&&|)")) {
|
Token::Match(tok, "%oror%|&& %var% %oror%|&&|)")) {
|
||||||
varid = tok->next()->varId();
|
varid = tok->next()->varId();
|
||||||
|
@ -111,6 +106,16 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip if variable is conditionally used in ?: expression.
|
||||||
|
const Token *parent = tok2->astParent();
|
||||||
|
while (parent && !Token::Match(parent, "[?:]"))
|
||||||
|
parent = parent->astParent();
|
||||||
|
if (parent) {
|
||||||
|
if (settings->debugwarnings)
|
||||||
|
bailout(tokenlist, errorLogger, tok2, "no simplification of " + tok2->str() + " within ?: expression");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tok2->values.push_back(val);
|
tok2->values.push_back(val);
|
||||||
if (var && tok2 == var->nameToken())
|
if (var && tok2 == var->nameToken())
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -76,17 +76,32 @@ private:
|
||||||
|
|
||||||
|
|
||||||
void valueFlowBeforeCondition() {
|
void valueFlowBeforeCondition() {
|
||||||
const char code[] = "void f(int x) {\n"
|
const char *code;
|
||||||
" int a = x;\n"
|
|
||||||
" if (x == 123) {}\n"
|
code = "void f(int x) {\n"
|
||||||
"}";
|
" int a = x;\n"
|
||||||
|
" if (x == 123) {}\n"
|
||||||
|
"}";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 2U, 123));
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 123));
|
||||||
|
|
||||||
// bailout: ?:
|
// bailout: ?:
|
||||||
bailout("void f(int x) {\n"
|
bailout("void f(int x) {\n"
|
||||||
" y = ((x<0) ? x : ((x==2)?3:4));\n"
|
" y = ((x<0) ? x : ((x==2)?3:4));\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (debug) ValueFlow bailout: variable x stopping on :\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (debug) ValueFlow bailout: no simplification of x within ?: expression\n", errout.str());
|
||||||
|
|
||||||
|
bailout("int f(int x) {\n"
|
||||||
|
" int r = x ? 1 / x : 0;\n"
|
||||||
|
" if (x == 0) {}\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (debug) ValueFlow bailout: no simplification of x within ?: expression\n", errout.str());
|
||||||
|
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" int a = x;\n"
|
||||||
|
" a = b ? x/2 : 20/x;\n"
|
||||||
|
" if (x == 123) {}\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 123));
|
||||||
|
|
||||||
// bailout: if/else/etc
|
// bailout: if/else/etc
|
||||||
bailout("void f(int x) {\n"
|
bailout("void f(int x) {\n"
|
||||||
|
|
Loading…
Reference in New Issue