Skip to content

Commit c0e8654

Browse files
committed
Refactor void* checking. Use ValueType.
1 parent fdcab8f commit c0e8654

2 files changed

Lines changed: 25 additions & 42 deletions

File tree

lib/checksizeof.cpp

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -334,47 +334,30 @@ void CheckSizeof::sizeofVoid()
334334
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
335335
if (Token::simpleMatch(tok, "sizeof ( )")) { // "sizeof(void)" gets simplified to sizeof ( )
336336
sizeofVoidError(tok);
337-
} else if (Token::Match(tok, "sizeof ( * %var% )") && tok->tokAt(3)->variable() &&
338-
(Token::Match(tok->tokAt(3)->variable()->typeStartToken(), "void * !!*")) &&
339-
(!tok->tokAt(3)->variable()->isArray())) { // sizeof(*p) where p is of type "void*"
340-
sizeofDereferencedVoidPointerError(tok, tok->strAt(3));
341-
} else if (Token::Match(tok, "%name% +|-|++|--") ||
342-
Token::Match(tok, "+|-|++|-- %name%")) { // Arithmetic operations on variable of type "void*"
343-
const int index = (tok->isName()) ? 0 : 1;
344-
const Variable* var = tok->tokAt(index)->variable();
345-
if (var && !var->isArray() && Token::Match(var->typeStartToken(), "void * !!*")) {
346-
std::string varname = tok->strAt(index);
347-
// In case this 'void *' var is a member then go back to the main object
348-
const Token* tok2 = tok->tokAt(index);
349-
if (index == 0) {
350-
bool isMember = false;
351-
while (Token::simpleMatch(tok2->previous(), ".")) {
352-
isMember = true;
353-
if (Token::simpleMatch(tok2->tokAt(-2), ")"))
354-
tok2 = tok2->linkAt(-2);
355-
else if (Token::simpleMatch(tok2->tokAt(-2), "]"))
356-
tok2 = tok2->linkAt(-2)->previous();
357-
else
358-
tok2 = tok2->tokAt(-2);
359-
}
360-
if (isMember) {
361-
// Get 'struct.member' complete name (without spaces)
362-
varname = tok2->stringifyList(tok->next());
363-
varname.erase(std::remove_if(varname.begin(), varname.end(),
364-
static_cast<int (*)(int)>(std::isspace)), varname.end());
365-
}
366-
}
367-
// Check for cast on operations with '+|-'
368-
if (Token::Match(tok, "%name% +|-")) {
369-
// Check for cast expression
370-
if (Token::simpleMatch(tok2->previous(), ")") && !Token::Match(tok2->previous()->link(), "( const| void *"))
371-
continue;
372-
if (tok2->strAt(-1) == "&") // Check for reference operator
373-
continue;
374-
}
375-
arithOperationsOnVoidPointerError(tok, varname,
376-
var->typeStartToken()->stringifyList(var->typeEndToken()->next()));
377-
}
337+
} else if (Token::Match(tok, "sizeof (") && tok->next()->astOperand2()) {
338+
const ValueType *vt = tok->next()->astOperand2()->valueType();
339+
if (vt && vt->type == ValueType::Type::VOID && vt->pointer == 0U)
340+
sizeofDereferencedVoidPointerError(tok, tok->strAt(3));
341+
} else if (tok->str() == "-") {
342+
// only warn for: 'void *' - 'integral'
343+
const ValueType *vt1 = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
344+
const ValueType *vt2 = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr;
345+
bool op1IsvoidPointer = (vt1 && vt1->type == ValueType::Type::VOID && vt1->pointer == 1U);
346+
bool op2IsIntegral = (vt2 && vt2->isIntegral() && vt2->pointer == 0U);
347+
if (op1IsvoidPointer && op2IsIntegral)
348+
arithOperationsOnVoidPointerError(tok, tok->astOperand1()->expressionString(), vt1->str());
349+
} else if (Token::Match(tok, "+|++|--|+=|-=")) { // Arithmetic operations on variable of type "void*"
350+
const ValueType *vt1 = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
351+
const ValueType *vt2 = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr;
352+
353+
bool voidpointer1 = (vt1 && vt1->type == ValueType::Type::VOID && vt1->pointer == 1U);
354+
bool voidpointer2 = (vt2 && vt2->type == ValueType::Type::VOID && vt2->pointer == 1U);
355+
356+
if (voidpointer1)
357+
arithOperationsOnVoidPointerError(tok, tok->astOperand1()->expressionString(), vt1->str());
358+
359+
if (!tok->isAssignmentOp() && voidpointer2)
360+
arithOperationsOnVoidPointerError(tok, tok->astOperand2()->expressionString(), vt2->str());
378361
}
379362
}
380363
}

test/testsizeof.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ class TestSizeof : public TestFixture {
659659
"[test.cpp:3]: (portability) 'data' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.\n", errout.str());
660660

661661
check("void f(void *data) {\n"
662-
" void* data2 = (void *)data + 1;\n"
662+
" void* data2 = data + 1;\n"
663663
"}");
664664
ASSERT_EQUALS("[test.cpp:2]: (portability) 'data' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.\n", errout.str());
665665

0 commit comments

Comments
 (0)