Skip to content

Commit 670c4de

Browse files
committed
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
1 parent ecafe7a commit 670c4de

10 files changed

Lines changed: 54 additions & 21 deletions

lib/checkmemoryleak.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
10791079
}
10801080
} else if (tok2->varId() && extravar.find(tok2->varId()) != extravar.end()) {
10811081
dep = true;
1082-
} else if (tok2->varId() == varid && tok2->next()->isOp())
1082+
} else if (tok2->varId() == varid && tok2->next()->isConstOp())
10831083
dep = true;
10841084
}
10851085

lib/checknullpointer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
324324
unknown = false;
325325

326326
// Dereferencing pointer..
327-
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"))
327+
if (tok->strAt(-1) == "*" && (Token::Match(tok->tokAt(-2), "return|throw|;|{|}|:|[|(|,") || tok->tokAt(-2)->isOp()) && !Token::Match(tok->tokAt(-3), "sizeof|decltype"))
328328
return true;
329329

330330
// read/write member variable
@@ -1129,7 +1129,7 @@ void CheckNullPointer::nullConstantDereference()
11291129
tok = tok->next()->link();
11301130

11311131
else if (Token::simpleMatch(tok, "* 0")) {
1132-
if (Token::Match(tok->previous(), "return|throw|;|{|}|:|[|(|,") || tok->previous()->isOp() || tok->previous()->isAssignmentOp()) {
1132+
if (Token::Match(tok->previous(), "return|throw|;|{|}|:|[|(|,") || tok->previous()->isOp()) {
11331133
nullPointerError(tok);
11341134
}
11351135
}
@@ -1406,8 +1406,8 @@ class Nullpointer : public ExecutionPath {
14061406
if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
14071407
setnull(checks, tok.varId());
14081408
else if (!deref &&
1409-
(!tok.previous()->isOp() || tok.previous()->str() == "&") && !tok.previous()->isAssignmentOp() &&
1410-
(!tok.next()->isOp() || tok.next()->str() == ">>"))
1409+
(!tok.previous()->isOp() || tok.previous()->str() == "&") &&
1410+
(!tok.next()->isConstOp() || tok.next()->str() == ">>"))
14111411
bailOutVar(checks, tok.varId()); // If its possible that the pointers value changes, bail out.
14121412
}
14131413

lib/checkother.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ void CheckOther::checkBitwiseOnBoolean()
389389
bitwiseOnBooleanError(tok->next(), var->name(), tok->strAt(2) == "&" ? "&&" : "||");
390390
tok = tok->tokAt(2);
391391
}
392-
} else if (Token::Match(tok, "[&|] %var% )|.|return|&&|%oror%|throw|,") && (!tok->previous() || !tok->previous()->isExtendedOp() || tok->strAt(-1) == ")")) {
392+
} else if (Token::Match(tok, "[&|] %var% )|.|return|&&|%oror%|throw|,") && (!tok->previous() || !tok->previous()->isExtendedOp() || tok->strAt(-1) == ")" || tok->strAt(-1) == "]")) {
393393
const Variable *var = tok->next()->variable();
394394
if (var && var->typeEndToken()->str() == "bool") {
395395
bitwiseOnBooleanError(tok->next(), var->name(), tok->str() == "&" ? "&&" : "||");
@@ -3526,7 +3526,7 @@ void CheckOther::sizeofCalculation()
35263526
if (Token::simpleMatch(tok, "sizeof (")) {
35273527
const Token* const end = tok->linkAt(1);
35283528
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
3529-
if (tok2->isOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
3529+
if (tok2->isConstOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
35303530
if (!(Token::Match(tok2->previous(), "%type%") || Token::Match(tok2->next(), "%type%"))) {
35313531
sizeofCalculationError(tok2, tok2->isExpandedMacro());
35323532
break;

lib/checkuninitvar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp
15301530
// is there something like: ; "*((&var ..expr.. =" => the variable is assigned
15311531
if (vartok->previous()->str() == "&") {
15321532
const Token *tok2 = vartok->tokAt(-2);
1533-
if (tok2 && (tok2->isOp() || tok2->str() == "("))
1533+
if (tok2 && (tok2->isConstOp() || tok2->str() == "("))
15341534
return false; // address of
15351535
if (Token::simpleMatch(tok2,")"))
15361536
tok2 = tok2->link()->previous();

lib/templatesimplifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
895895
}
896896

897897
if (Token::simpleMatch(tok->previous(), "* 1") || Token::simpleMatch(tok, "1 *")) {
898-
if (tok->previous() && tok->previous()->isOp())
898+
if (tok->previous() && tok->previous()->isConstOp())
899899
tok = tok->previous();
900900
tok->deleteNext();
901901
tok->deleteThis();
@@ -916,7 +916,7 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
916916
Token::simpleMatch(tok->previous(), "| 0 )") ||
917917
Token::simpleMatch(tok->previous(), "( 1 &&") ||
918918
Token::simpleMatch(tok->previous(), "&& 1 )")) {
919-
if (tok->previous()->isOp())
919+
if (tok->previous()->isConstOp())
920920
tok = tok->previous();
921921
tok->deleteNext();
922922
tok->deleteThis();

lib/token.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ static int multiComparePercent(const Token *tok, const char * * haystack_p,
312312
if (haystack[1] == 'o' && // "%op%"
313313
haystack[2] == 'p' &&
314314
haystack[3] == '%') {
315-
if (tok->isOp())
315+
if (tok->isConstOp())
316316
return 1;
317317
*haystack_p = haystack = haystack + 4;
318318
} else if (haystack[1] == 'o' && // "%or%"
@@ -349,7 +349,7 @@ int Token::multiCompare(const Token *tok, const char *haystack, const char *need
349349
haystack[3] == '%' &&
350350
haystack[4] == '|') {
351351
haystack = haystack + 5;
352-
if (tok->isOp())
352+
if (tok->isConstOp())
353353
return 1;
354354
} else if (haystack[2] == 'r' && // "%or%|"
355355
haystack[3] == '%' &&
@@ -627,7 +627,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
627627
// Op (%op%)
628628
if (p[0] == 'p') {
629629
p += 2;
630-
multicompare(p,tok->isOp(),ismulticomp);
630+
multicompare(p,tok->isConstOp(),ismulticomp);
631631
}
632632
// Or (%or%)
633633
else {

lib/token.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class CPPCHECKLIB Token {
135135
* - "%comp%" Any token such that isComparisonOp() returns true.
136136
* - "%str%" Any token starting with &quot;-character (C-string).
137137
* - "%varid%" Match with parameter varid
138-
* - "%op%" Any token such that isOp() returns true.
138+
* - "%op%" Any token such that isConstOp() returns true.
139139
* - "%or%" A bitwise-or operator '|'
140140
* - "%oror%" A logical-or operator '||'
141141
* - "[abc]" Any of the characters 'a' or 'b' or 'c'
@@ -204,19 +204,24 @@ class CPPCHECKLIB Token {
204204
bool isNumber() const {
205205
return _type == eNumber;
206206
}
207-
bool isArithmeticalOp() const {
208-
return _type == eArithmeticalOp;
209-
}
210207
bool isOp() const {
208+
return (isConstOp() ||
209+
isAssignmentOp() ||
210+
_type == eIncDecOp);
211+
}
212+
bool isConstOp() const {
211213
return (isArithmeticalOp() ||
212214
_type == eLogicalOp ||
213215
_type == eComparisonOp ||
214216
_type == eBitOp);
215217
}
216218
bool isExtendedOp() const {
217-
return isOp() ||
219+
return isConstOp() ||
218220
_type == eExtendedOp;
219221
}
222+
bool isArithmeticalOp() const {
223+
return _type == eArithmeticalOp;
224+
}
220225
bool isComparisonOp() const {
221226
return _type == eComparisonOp;
222227
}

lib/tokenize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4214,7 +4214,7 @@ void Tokenizer::simplifyCompoundAssignment()
42144214
break;
42154215
}
42164216

4217-
someOperator |= (tok2->isOp() || (tok2->str() == "?") || tok2->isAssignmentOp());
4217+
someOperator |= (tok2->isOp() || tok2->str() == "?");
42184218
}
42194219
}
42204220

lib/tokenlist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ void TokenList::createAst()
393393
const std::string op(operators[i]);
394394
for (Token *tok = _front; tok; tok = tok->next()) {
395395
if (tok->astOperand1()==NULL && op.find(" "+tok->str()+" ")!=std::string::npos) {
396-
if (tok->str() != "++" && tok->str() != "--") {
396+
if (tok->type() != Token::eIncDecOp) {
397397
tok->astOperand1(tok->previous());
398398
tok->astOperand2(tok->next());
399399
} else if (tok->previous() && !tok->previous()->isOp()) {

test/testtoken.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class TestToken : public TestFixture {
6868

6969
TEST_CASE(isArithmeticalOp);
7070
TEST_CASE(isOp);
71+
TEST_CASE(isConstOp);
7172
TEST_CASE(isExtendedOp);
7273
TEST_CASE(isAssignmentOp);
7374
TEST_CASE(isStandardType);
@@ -569,6 +570,7 @@ class TestToken : public TestFixture {
569570
append_vector(test_ops, bitOps);
570571
append_vector(test_ops, comparisonOps);
571572
append_vector(test_ops, logicalOps);
573+
append_vector(test_ops, assignmentOps);
572574

573575
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
574576
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
@@ -580,7 +582,6 @@ class TestToken : public TestFixture {
580582
// Negative test against other operators
581583
std::vector<std::string> other_ops;
582584
append_vector(other_ops, extendedOps);
583-
append_vector(other_ops, assignmentOps);
584585

585586
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
586587
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
@@ -590,6 +591,33 @@ class TestToken : public TestFixture {
590591
}
591592
}
592593

594+
void isConstOp() {
595+
std::vector<std::string> test_ops;
596+
append_vector(test_ops, arithmeticalOps);
597+
append_vector(test_ops, bitOps);
598+
append_vector(test_ops, comparisonOps);
599+
append_vector(test_ops, logicalOps);
600+
601+
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
602+
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
603+
Token tok(NULL);
604+
tok.str(*test_op);
605+
ASSERT_EQUALS(true, tok.isConstOp());
606+
}
607+
608+
// Negative test against other operators
609+
std::vector<std::string> other_ops;
610+
append_vector(other_ops, extendedOps);
611+
append_vector(other_ops, assignmentOps);
612+
613+
std::vector<std::string>::const_iterator other_op, other_ops_end = other_ops.end();
614+
for (other_op = other_ops.begin(); other_op != other_ops_end; ++other_op) {
615+
Token tok(NULL);
616+
tok.str(*other_op);
617+
ASSERT_EQUALS_MSG(false, tok.isConstOp(), "Failing normal operator: " + *other_op);
618+
}
619+
}
620+
593621
void isExtendedOp() {
594622
std::vector<std::string> test_ops;
595623
append_vector(test_ops, arithmeticalOps);

0 commit comments

Comments
 (0)