Refactoring Check64BitPortability. Use ValueType.
This commit is contained in:
parent
7f1b43e79c
commit
5216f904e7
|
@ -30,18 +30,6 @@ namespace {
|
|||
Check64BitPortability instance;
|
||||
}
|
||||
|
||||
/** Is given variable a pointer or array? */
|
||||
static bool isaddr(const Variable *var)
|
||||
{
|
||||
return (var && (var->isPointer() || var->isArray()));
|
||||
}
|
||||
|
||||
/** Is given variable an integer variable */
|
||||
static bool isint(const Variable *var)
|
||||
{
|
||||
return (var && var->isIntegralType() && !var->isArrayOrPointer() && var->typeStartToken()->str() != "bool");
|
||||
}
|
||||
|
||||
void Check64BitPortability::pointerassignment()
|
||||
{
|
||||
if (!_settings->isEnabled("portability"))
|
||||
|
@ -65,30 +53,21 @@ void Check64BitPortability::pointerassignment()
|
|||
continue;
|
||||
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "return %name%|%num% [;+]") && !Token::simpleMatch(tok, "return 0 ;")) {
|
||||
enum { NO, INT, PTR, PTRDIFF } type = NO;
|
||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||
if ((type == NO || type == INT) && Token::Match(tok2, "%var% [+;]") && isaddr(tok2->variable()))
|
||||
type = PTR;
|
||||
else if (type == NO && (tok2->isNumber() || isint(tok2->variable())))
|
||||
type = INT;
|
||||
else if (type == PTR && Token::Match(tok2, "- %var%") && isaddr(tok2->next()->variable()))
|
||||
type = PTRDIFF;
|
||||
else if (tok2->str() == "(") {
|
||||
// TODO: handle parentheses
|
||||
type = NO;
|
||||
break;
|
||||
} else if (type == PTR && Token::simpleMatch(tok2, "."))
|
||||
type = NO; // Reset after pointer reference, see #4642
|
||||
else if (tok2->str() == ";")
|
||||
break;
|
||||
}
|
||||
if (tok->str() != "return")
|
||||
continue;
|
||||
|
||||
if (retPointer && (type == INT || type == PTRDIFF))
|
||||
returnIntegerError(tok);
|
||||
else if (!retPointer && type == PTR)
|
||||
returnPointerError(tok);
|
||||
}
|
||||
if (!tok->astOperand1() || tok->astOperand1()->isNumber())
|
||||
continue;
|
||||
|
||||
const ValueType * const returnType = tok->astOperand1()->valueType();
|
||||
if (!returnType)
|
||||
continue;
|
||||
|
||||
if (retPointer && returnType->pointer == 0U)
|
||||
returnIntegerError(tok);
|
||||
|
||||
if (!retPointer && returnType->pointer >= 1U)
|
||||
returnPointerError(tok);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,28 +75,27 @@ void Check64BitPortability::pointerassignment()
|
|||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "[;{}] %var% = %name%")) {
|
||||
const Token* tok2 = tok->tokAt(3);
|
||||
while (Token::Match(tok2->next(), ".|::"))
|
||||
tok2 = tok2->tokAt(2);
|
||||
if (!Token::Match(tok2, "%var% ;|+"))
|
||||
continue;
|
||||
if (tok->str() != "=")
|
||||
continue;
|
||||
|
||||
const Variable *var1(tok->next()->variable());
|
||||
const Variable *var2(tok2->variable());
|
||||
const ValueType *lhstype = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
|
||||
const ValueType *rhstype = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr;
|
||||
if (!lhstype || !rhstype)
|
||||
continue;
|
||||
|
||||
if (isaddr(var1) && isint(var2) && tok2->strAt(1) != "+")
|
||||
assignmentIntegerToAddressError(tok->next());
|
||||
// Assign integer to pointer..
|
||||
if (lhstype->pointer >= 1U &&
|
||||
rhstype->pointer == 0U &&
|
||||
rhstype->originalTypeName.empty() &&
|
||||
rhstype->type == ValueType::Type::INT)
|
||||
assignmentIntegerToAddressError(tok);
|
||||
|
||||
else if (isint(var1) && isaddr(var2) && !tok2->isPointerCompare()) {
|
||||
// assigning address => warning
|
||||
// some trivial addition => warning
|
||||
if (Token::Match(tok2->next(), "+ %any% !!;"))
|
||||
continue;
|
||||
|
||||
assignmentAddressToIntegerError(tok->next());
|
||||
}
|
||||
}
|
||||
// Assign pointer to integer..
|
||||
if (rhstype->pointer >= 1U &&
|
||||
lhstype->pointer == 0U &&
|
||||
lhstype->originalTypeName.empty() &&
|
||||
lhstype->type == ValueType::Type::INT)
|
||||
assignmentAddressToIntegerError(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ private:
|
|||
" int x = 10;\n"
|
||||
" int *a = x * x;\n"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("error", "", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an integer to a pointer is not portable.\n", errout.str());
|
||||
|
||||
check("void foo(int *start, int *end) {\n"
|
||||
" int len;\n"
|
||||
|
|
Loading…
Reference in New Issue