From 4b72f01e99aca95c0186c8df7719da41d446e83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 28 Dec 2013 11:02:39 +0100 Subject: [PATCH] clarify calculation: Fixed FP for 'a = (*p ? 1 : 2)' --- lib/checkother.cpp | 2 +- lib/checksizeof.cpp | 42 +----------------------------------------- lib/token.cpp | 37 +++++++++++++++++++++++++++++++++++++ lib/token.h | 9 +++++++++ test/testother.cpp | 3 +++ 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 5747b8632..10f7fb3a1 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -180,7 +180,7 @@ void CheckOther::clarifyCalculation() const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { // ? operator where lhs is arithmetical expression - if (tok->str() != "?" || !tok->astOperand1() || !tok->astOperand1()->isArithmeticalOp()) + if (tok->str() != "?" || !tok->astOperand1() || !tok->astOperand1()->isArithmeticalOp() || !tok->astOperand1()->isCalculation()) continue; // Is code clarified by parentheses already? diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 944a47993..63795f011 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -22,7 +22,6 @@ #include "symboldatabase.h" #include #include -#include //--------------------------------------------------------------------------- // Register this check class (by creating a static instance of it) @@ -219,45 +218,6 @@ void CheckSizeof::sizeofsizeofError(const Token *tok) } //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -static bool isCalculation(const Token *op) -{ - if (!op) - return false; - - if (!Token::Match(op, "%cop%|++|--")) - return false; - - if (Token::Match(op, "*|&")) { - // dereference or address-of? - if (!op->astOperand2()) - return false; - - if (op->astOperand2()->str() == "[") - return false; - - // type specification? - std::stack operands; - operands.push(op); - while (!operands.empty()) { - const Token *item = operands.top(); - operands.pop(); - if (item->isNumber() || item->varId() > 0) - return true; - if (item->astOperand1()) - operands.push(item->astOperand1()); - if (item->astOperand2()) - operands.push(item->astOperand2()); - else if (Token::Match(item, "*|&")) - return false; - } - - // type specification => return false - return false; - } - - return true; -} void CheckSizeof::sizeofCalculation() { @@ -267,7 +227,7 @@ void CheckSizeof::sizeofCalculation() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "sizeof (")) { const Token *argument = tok->next()->astOperand2(); - if (isCalculation(argument) && (!argument->isExpandedMacro() || _settings->inconclusive)) + if (argument && argument->isCalculation() && (!argument->isExpandedMacro() || _settings->inconclusive)) sizeofCalculationError(argument, argument->isExpandedMacro()); } } diff --git a/lib/token.cpp b/lib/token.cpp index 4c7496a5c..a069f73dd 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -27,6 +27,7 @@ #include #include #include +#include Token::Token(Token **t) : tokensBack(t), @@ -1143,6 +1144,42 @@ void Token::astOperand2(Token *tok) _astOperand2 = tok; } +bool Token::isCalculation() const +{ + if (!Token::Match(this, "%cop%|++|--")) + return false; + + if (Token::Match(this, "*|&")) { + // dereference or address-of? + if (!this->astOperand2()) + return false; + + if (this->astOperand2()->str() == "[") + return false; + + // type specification? + std::stack operands; + operands.push(this); + while (!operands.empty()) { + const Token *op = operands.top(); + operands.pop(); + if (op->isNumber() || op->varId() > 0) + return true; + if (op->astOperand1()) + operands.push(op->astOperand1()); + if (op->astOperand2()) + operands.push(op->astOperand2()); + else if (Token::Match(op, "*|&")) + return false; + } + + // type specification => return false + return false; + } + + return true; +} + void Token::printAst() const { bool title = false; diff --git a/lib/token.h b/lib/token.h index d635cd7dc..13e5bb6c5 100644 --- a/lib/token.h +++ b/lib/token.h @@ -672,6 +672,15 @@ public: return ret; } + /** + * Is current token a calculation? Only true for operands. + * For '*' and '&' tokens it is looked up if this is a + * dereference or address-of. A dereference or address-of is not + * counted as a calculation. + * @return returns true if current token is a calculation + */ + bool isCalculation() const; + void clearAst() { _astOperand1 = _astOperand2 = _astParent = NULL; } diff --git a/test/testother.cpp b/test/testother.cpp index 482f1a2c7..6602cd4e0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4174,6 +4174,9 @@ private: " return shift < sizeof(int64_t)*8 ? 1 : 2;\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("void f() { a = *p ? 1 : 2; }"); + ASSERT_EQUALS("", errout.str()); } void clarifyStatement() {