Skip to content

Commit eb2ea1c

Browse files
committed
AST: refactored CheckSizeof::sizeofCalculation()
1 parent 26dfdda commit eb2ea1c

1 file changed

Lines changed: 38 additions & 10 deletions

File tree

lib/checksizeof.cpp

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "symboldatabase.h"
2323
#include <algorithm>
2424
#include <cctype>
25+
#include <stack>
2526
//---------------------------------------------------------------------------
2627

2728
// Register this check class (by creating a static instance of it)
@@ -219,23 +220,50 @@ void CheckSizeof::sizeofsizeofError(const Token *tok)
219220

220221
//-----------------------------------------------------------------------------
221222
//-----------------------------------------------------------------------------
223+
static bool isCalculation(const Token *op)
224+
{
225+
if (!op)
226+
return false;
227+
228+
if (!Token::Match(op, "%cop%|++|--"))
229+
return false;
230+
231+
if (Token::Match(op, "*|&")) {
232+
// dereference or address-of?
233+
if (!op->astOperand2())
234+
return false;
235+
236+
// type specification?
237+
std::stack<const Token *> operands;
238+
operands.push(op);
239+
while (!operands.empty()) {
240+
const Token *item = operands.top();
241+
operands.pop();
242+
if (item->isNumber() || item->varId() > 0)
243+
return true;
244+
if (item->astOperand1())
245+
operands.push(item->astOperand1());
246+
if (item->astOperand2())
247+
operands.push(item->astOperand2());
248+
}
249+
250+
// type specification => return false
251+
return false;
252+
}
253+
254+
return true;
255+
}
256+
222257
void CheckSizeof::sizeofCalculation()
223258
{
224259
if (!_settings->isEnabled("warning"))
225260
return;
226261

227262
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
228263
if (Token::simpleMatch(tok, "sizeof (")) {
229-
const Token* const end = tok->linkAt(1);
230-
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
231-
if (tok2->isConstOp() && (!tok2->isExpandedMacro() || _settings->inconclusive) && !Token::Match(tok2, ">|<|&") && (Token::Match(tok2->previous(), "%var%") || tok2->str() != "*")) {
232-
if (!(Token::Match(tok2->previous(), "%type%") || Token::Match(tok2->next(), "%type%"))) {
233-
sizeofCalculationError(tok2, tok2->isExpandedMacro());
234-
break;
235-
}
236-
} else if (tok2->type() == Token::eIncDecOp)
237-
sizeofCalculationError(tok2, tok2->isExpandedMacro());
238-
}
264+
const Token *argument = tok->next()->astOperand2();
265+
if (isCalculation(argument) && (!argument->isExpandedMacro() || _settings->inconclusive))
266+
sizeofCalculationError(argument, argument->isExpandedMacro());
239267
}
240268
}
241269
}

0 commit comments

Comments
 (0)