AST: refactored CheckSizeof::sizeofCalculation()

This commit is contained in:
Daniel Marjamäki 2013-12-25 12:35:41 +01:00
parent 26dfddac6b
commit eb2ea1c28f
1 changed files with 38 additions and 10 deletions

View File

@ -22,6 +22,7 @@
#include "symboldatabase.h"
#include <algorithm>
#include <cctype>
#include <stack>
//---------------------------------------------------------------------------
// 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<const Token *> 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());
}
}
}