Changed behaviour of Token::is*Op() functions:

- Rename Token::isOp() to Token::isConstOp() (indicating that the operator does _not_ modify the input variables)
- Create new Token::isOp(), returning true also for ++, -- and assignment operators
- Make Token::isExtendedOp() returning also true for all assignment and ++/-- operators
This commit is contained in:
PKEuS 2013-02-28 12:50:29 -08:00
parent ecafe7a129
commit 670c4de8a9
10 changed files with 54 additions and 21 deletions

View File

@ -1079,7 +1079,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
}
} else if (tok2->varId() && extravar.find(tok2->varId()) != extravar.end()) {
dep = true;
} else if (tok2->varId() == varid && tok2->next()->isOp())
} else if (tok2->varId() == varid && tok2->next()->isConstOp())
dep = true;
}

View File

@ -324,7 +324,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
unknown = false;
// Dereferencing pointer..
if (tok->strAt(-1) == "*" && (Token::Match(tok->tokAt(-2), "return|throw|;|{|}|:|[|(|,") || tok->tokAt(-2)->isOp() || tok->tokAt(-2)->isAssignmentOp()) && !Token::Match(tok->tokAt(-3), "sizeof|decltype"))
if (tok->strAt(-1) == "*" && (Token::Match(tok->tokAt(-2), "return|throw|;|{|}|:|[|(|,") || tok->tokAt(-2)->isOp()) && !Token::Match(tok->tokAt(-3), "sizeof|decltype"))
return true;
// read/write member variable
@ -1129,7 +1129,7 @@ void CheckNullPointer::nullConstantDereference()
tok = tok->next()->link();
else if (Token::simpleMatch(tok, "* 0")) {
if (Token::Match(tok->previous(), "return|throw|;|{|}|:|[|(|,") || tok->previous()->isOp() || tok->previous()->isAssignmentOp()) {
if (Token::Match(tok->previous(), "return|throw|;|{|}|:|[|(|,") || tok->previous()->isOp()) {
nullPointerError(tok);
}
}
@ -1406,8 +1406,8 @@ private:
if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
setnull(checks, tok.varId());
else if (!deref &&
(!tok.previous()->isOp() || tok.previous()->str() == "&") && !tok.previous()->isAssignmentOp() &&
(!tok.next()->isOp() || tok.next()->str() == ">>"))
(!tok.previous()->isOp() || tok.previous()->str() == "&") &&
(!tok.next()->isConstOp() || tok.next()->str() == ">>"))
bailOutVar(checks, tok.varId()); // If its possible that the pointers value changes, bail out.
}

View File

@ -389,7 +389,7 @@ void CheckOther::checkBitwiseOnBoolean()
bitwiseOnBooleanError(tok->next(), var->name(), tok->strAt(2) == "&" ? "&&" : "||");
tok = tok->tokAt(2);
}
} else if (Token::Match(tok, "[&|] %var% )|.|return|&&|%oror%|throw|,") && (!tok->previous() || !tok->previous()->isExtendedOp() || tok->strAt(-1) == ")")) {
} else if (Token::Match(tok, "[&|] %var% )|.|return|&&|%oror%|throw|,") && (!tok->previous() || !tok->previous()->isExtendedOp() || tok->strAt(-1) == ")" || tok->strAt(-1) == "]")) {
const Variable *var = tok->next()->variable();
if (var && var->typeEndToken()->str() == "bool") {
bitwiseOnBooleanError(tok->next(), var->name(), tok->str() == "&" ? "&&" : "||");
@ -3526,7 +3526,7 @@ void CheckOther::sizeofCalculation()
if (Token::simpleMatch(tok, "sizeof (")) {
const Token* const end = tok->linkAt(1);
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
if (tok2->isOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
if (tok2->isConstOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
if (!(Token::Match(tok2->previous(), "%type%") || Token::Match(tok2->next(), "%type%"))) {
sizeofCalculationError(tok2, tok2->isExpandedMacro());
break;

View File

@ -1530,7 +1530,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp
// is there something like: ; "*((&var ..expr.. =" => the variable is assigned
if (vartok->previous()->str() == "&") {
const Token *tok2 = vartok->tokAt(-2);
if (tok2 && (tok2->isOp() || tok2->str() == "("))
if (tok2 && (tok2->isConstOp() || tok2->str() == "("))
return false; // address of
if (Token::simpleMatch(tok2,")"))
tok2 = tok2->link()->previous();

View File

@ -895,7 +895,7 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
}
if (Token::simpleMatch(tok->previous(), "* 1") || Token::simpleMatch(tok, "1 *")) {
if (tok->previous() && tok->previous()->isOp())
if (tok->previous() && tok->previous()->isConstOp())
tok = tok->previous();
tok->deleteNext();
tok->deleteThis();
@ -916,7 +916,7 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
Token::simpleMatch(tok->previous(), "| 0 )") ||
Token::simpleMatch(tok->previous(), "( 1 &&") ||
Token::simpleMatch(tok->previous(), "&& 1 )")) {
if (tok->previous()->isOp())
if (tok->previous()->isConstOp())
tok = tok->previous();
tok->deleteNext();
tok->deleteThis();

View File

@ -312,7 +312,7 @@ static int multiComparePercent(const Token *tok, const char * * haystack_p,
if (haystack[1] == 'o' && // "%op%"
haystack[2] == 'p' &&
haystack[3] == '%') {
if (tok->isOp())
if (tok->isConstOp())
return 1;
*haystack_p = haystack = haystack + 4;
} else if (haystack[1] == 'o' && // "%or%"
@ -349,7 +349,7 @@ int Token::multiCompare(const Token *tok, const char *haystack, const char *need
haystack[3] == '%' &&
haystack[4] == '|') {
haystack = haystack + 5;
if (tok->isOp())
if (tok->isConstOp())
return 1;
} else if (haystack[2] == 'r' && // "%or%|"
haystack[3] == '%' &&
@ -627,7 +627,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
// Op (%op%)
if (p[0] == 'p') {
p += 2;
multicompare(p,tok->isOp(),ismulticomp);
multicompare(p,tok->isConstOp(),ismulticomp);
}
// Or (%or%)
else {

View File

@ -135,7 +135,7 @@ public:
* - "%comp%" Any token such that isComparisonOp() returns true.
* - "%str%" Any token starting with &quot;-character (C-string).
* - "%varid%" Match with parameter varid
* - "%op%" Any token such that isOp() returns true.
* - "%op%" Any token such that isConstOp() returns true.
* - "%or%" A bitwise-or operator '|'
* - "%oror%" A logical-or operator '||'
* - "[abc]" Any of the characters 'a' or 'b' or 'c'
@ -204,19 +204,24 @@ public:
bool isNumber() const {
return _type == eNumber;
}
bool isArithmeticalOp() const {
return _type == eArithmeticalOp;
}
bool isOp() const {
return (isConstOp() ||
isAssignmentOp() ||
_type == eIncDecOp);
}
bool isConstOp() const {
return (isArithmeticalOp() ||
_type == eLogicalOp ||
_type == eComparisonOp ||
_type == eBitOp);
}
bool isExtendedOp() const {
return isOp() ||
return isConstOp() ||
_type == eExtendedOp;
}
bool isArithmeticalOp() const {
return _type == eArithmeticalOp;
}
bool isComparisonOp() const {
return _type == eComparisonOp;
}

View File

@ -4214,7 +4214,7 @@ void Tokenizer::simplifyCompoundAssignment()
break;
}
someOperator |= (tok2->isOp() || (tok2->str() == "?") || tok2->isAssignmentOp());
someOperator |= (tok2->isOp() || tok2->str() == "?");
}
}

View File

@ -393,7 +393,7 @@ void TokenList::createAst()
const std::string op(operators[i]);
for (Token *tok = _front; tok; tok = tok->next()) {
if (tok->astOperand1()==NULL && op.find(" "+tok->str()+" ")!=std::string::npos) {
if (tok->str() != "++" && tok->str() != "--") {
if (tok->type() != Token::eIncDecOp) {
tok->astOperand1(tok->previous());
tok->astOperand2(tok->next());
} else if (tok->previous() && !tok->previous()->isOp()) {

View File

@ -68,6 +68,7 @@ private:
TEST_CASE(isArithmeticalOp);
TEST_CASE(isOp);
TEST_CASE(isConstOp);
TEST_CASE(isExtendedOp);
TEST_CASE(isAssignmentOp);
TEST_CASE(isStandardType);
@ -569,6 +570,7 @@ private:
append_vector(test_ops, bitOps);
append_vector(test_ops, comparisonOps);
append_vector(test_ops, logicalOps);
append_vector(test_ops, assignmentOps);
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
@ -580,7 +582,6 @@ private:
// Negative test against other operators
std::vector<std::string> other_ops;
append_vector(other_ops, extendedOps);
append_vector(other_ops, assignmentOps);
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
@ -590,6 +591,33 @@ private:
}
}
void isConstOp() {
std::vector<std::string> test_ops;
append_vector(test_ops, arithmeticalOps);
append_vector(test_ops, bitOps);
append_vector(test_ops, comparisonOps);
append_vector(test_ops, logicalOps);
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
Token tok(NULL);
tok.str(*test_op);
ASSERT_EQUALS(true, tok.isConstOp());
}
// Negative test against other operators
std::vector<std::string> other_ops;
append_vector(other_ops, extendedOps);
append_vector(other_ops, assignmentOps);
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
Token tok(NULL);
tok.str(*other_op);
ASSERT_EQUALS_MSG(false, tok.isConstOp(), "Failing normal operator: " + *other_op);
}
}
void isExtendedOp() {
std::vector<std::string> test_ops;
append_vector(test_ops, arithmeticalOps);