@@ -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}
0 commit comments