Skip to content

Commit f4cdb2c

Browse files
committed
CheckOther::checkCharVariable: Refactoring using AST
1 parent 5953f02 commit f4cdb2c

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

lib/checkother.cpp

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
20872103
void 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

Comments
 (0)