AST: refactored CheckSizeof::sizeofCalculation()
This commit is contained in:
parent
26dfddac6b
commit
eb2ea1c28f
|
@ -22,6 +22,7 @@
|
||||||
#include "symboldatabase.h"
|
#include "symboldatabase.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <stack>
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// 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()
|
void CheckSizeof::sizeofCalculation()
|
||||||
{
|
{
|
||||||
if (!_settings->isEnabled("warning"))
|
if (!_settings->isEnabled("warning"))
|
||||||
|
@ -226,16 +261,9 @@ void CheckSizeof::sizeofCalculation()
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "sizeof (")) {
|
if (Token::simpleMatch(tok, "sizeof (")) {
|
||||||
const Token* const end = tok->linkAt(1);
|
const Token *argument = tok->next()->astOperand2();
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
|
if (isCalculation(argument) && (!argument->isExpandedMacro() || _settings->inconclusive))
|
||||||
if (tok2->isConstOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
|
sizeofCalculationError(argument, argument->isExpandedMacro());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue