From eb2ea1c28f76cbc1f5be8185b7a12abfad57b8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 25 Dec 2013 12:35:41 +0100 Subject: [PATCH] AST: refactored CheckSizeof::sizeofCalculation() --- lib/checksizeof.cpp | 48 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 3f903fbb5..214b60abf 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -22,6 +22,7 @@ #include "symboldatabase.h" #include #include +#include //--------------------------------------------------------------------------- // Register this check class (by creating a static instance of it) @@ -219,6 +220,40 @@ 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; + + // 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()); + } + + // type specification => return false + return false; + } + + return true; +} + void CheckSizeof::sizeofCalculation() { if (!_settings->isEnabled("warning")) @@ -226,16 +261,9 @@ void CheckSizeof::sizeofCalculation() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { 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->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; - } - } else if (tok2->type() == Token::eIncDecOp) - sizeofCalculationError(tok2, tok2->isExpandedMacro()); - } + const Token *argument = tok->next()->astOperand2(); + if (isCalculation(argument) && (!argument->isExpandedMacro() || _settings->inconclusive)) + sizeofCalculationError(argument, argument->isExpandedMacro()); } } }