@@ -2084,6 +2084,22 @@ static bool isSignedChar(const Variable* var)
20842084 return (isChar (var) && !var->typeStartToken ()->isUnsigned ());
20852085}
20862086
2087+ static bool astIsSignedChar (const Token *tok)
2088+ {
2089+ if (!tok)
2090+ return false ;
2091+ if (tok->str () == " *" && tok->astOperand1 () && !tok->astOperand2 ()) {
2092+ const Variable *var = tok->astOperand1 ()->variable ();
2093+ if (!var || !var->isPointer ())
2094+ return false ;
2095+ const Token *type = var ? var->typeStartToken () : nullptr ;
2096+ while (type && type->str () == " const" )
2097+ type = type->next ();
2098+ return (type && type->str () == " char" && !type->isUnsigned ());
2099+ }
2100+ return isSignedChar (tok->variable ());
2101+ }
2102+
20872103void CheckOther::checkCharVariable ()
20882104{
20892105 if (!_settings->isEnabled (" warning" ))
@@ -2094,46 +2110,41 @@ void CheckOther::checkCharVariable()
20942110 for (std::size_t i = 0 ; i < functions; ++i) {
20952111 const Scope * scope = symbolDatabase->functionScopes [i];
20962112 for (const Token* tok = scope->classStart ; tok != scope->classEnd ; tok = tok->next ()) {
2097- if ((tok-> str () != " . " ) && Token::Match (tok-> next () , " %var% [ %var% ]" )) {
2113+ if (Token::Match (tok, " !!. %var% [ %var% ]" )) {
20982114 const Variable* arrayvar = tok->next ()->variable ();
20992115 const Variable* indexvar = tok->tokAt (3 )->variable ();
21002116 const MathLib::bigint arraysize = (arrayvar && arrayvar->isArray ()) ? arrayvar->dimension (0U ) : 0 ;
21012117 if (isSignedChar (indexvar) && arraysize > 0x80 )
21022118 charArrayIndexError (tok->next ());
21032119 }
21042120
2105- else if (Token::Match (tok, " [;{}] %var% = %any% [&^|] %any% ;" )) {
2106- // is a char variable used in the calculation?
2107- if (!isSignedChar (tok->tokAt (3 )->variable ()) &&
2108- !isSignedChar (tok->tokAt (5 )->variable ()))
2121+ else if (Token::Match (tok, " [&|^]" )) {
2122+ const Token *tok2;
2123+ if (tok->astOperand1 () && astIsSignedChar (tok->astOperand1 ()))
2124+ tok2 = tok->astOperand2 ();
2125+ else if (tok->astOperand2 () && astIsSignedChar (tok->astOperand2 ()))
2126+ tok2 = tok->astOperand1 ();
2127+ else
21092128 continue ;
21102129
21112130 // it's ok with a bitwise and where the other operand is 0xff or less..
2112- if (tok->strAt (4 ) == " &" ) {
2113- if (tok->tokAt (3 )->isNumber () && MathLib::isGreater (" 0x100" , tok->strAt (3 )))
2114- continue ;
2115- if (tok->tokAt (5 )->isNumber () && MathLib::isGreater (" 0x100" , tok->strAt (5 )))
2116- continue ;
2117- }
2118-
2119- // is the result stored in a short|int|long?
2120- const Variable *var = tok->next ()->variable ();
2121- if (var && Token::Match (var->typeStartToken (), " short|int|long" ) && !var->isPointer () && !var->isArray ())
2122- charBitOpError (tok->tokAt (4 )); // This is an error..
2123- }
2124-
2125- else if (Token::Match (tok, " [;{}] %var% = %any% [&^|] ( * %var% ) ;" )) {
2126- const Variable* var = tok->tokAt (7 )->variable ();
2127- if (!var || !var->isPointer () || var->typeStartToken ()->str () != " char" || var->typeStartToken ()->isUnsigned ())
2128- continue ;
2129- // it's ok with a bitwise and where the other operand is 0xff or less..
2130- if (tok->strAt (4 ) == " &" && tok->tokAt (3 )->isNumber () && MathLib::isGreater (" 0x100" , tok->strAt (3 )))
2131+ if (tok->str () == " &" && tok2 && tok2->isNumber () && MathLib::isGreater (" 0x100" , tok2->str ()))
21312132 continue ;
21322133
21332134 // is the result stored in a short|int|long?
2134- var = tok->next ()->variable ();
2135- if (var && Token::Match (var->typeStartToken (), " short|int|long" ) && !var->isPointer () && !var->isArray ())
2136- charBitOpError (tok->tokAt (4 )); // This is an error..
2135+ if (tok->astParent () && tok->astParent ()->str () == " =" ) {
2136+ const Token *eq = tok->astParent ();
2137+ const Token *lhs = eq->astOperand1 ();
2138+ if (lhs && lhs->str () == " *" && !lhs->astOperand2 ())
2139+ lhs = lhs->astOperand1 ();
2140+ while (lhs && lhs->str () == " ." )
2141+ lhs = lhs->astOperand2 ();
2142+ if (!lhs || !lhs->isName ())
2143+ continue ;
2144+ const Variable *var = lhs->variable ();
2145+ if (var && Token::Match (var->typeStartToken (), " short|int|long" ))
2146+ charBitOpError (tok); // This is an error..
2147+ }
21372148 }
21382149 }
21392150 }
0 commit comments