Refactoring Check64BitPortability. Use ValueType.

This commit is contained in:
Daniel Marjamäki 2015-12-30 19:59:23 +01:00
parent 7f1b43e79c
commit 5216f904e7
2 changed files with 33 additions and 55 deletions

View File

@ -30,18 +30,6 @@ namespace {
Check64BitPortability instance; 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() void Check64BitPortability::pointerassignment()
{ {
if (!_settings->isEnabled("portability")) if (!_settings->isEnabled("portability"))
@ -65,30 +53,21 @@ void Check64BitPortability::pointerassignment()
continue; continue;
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { 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 ;")) { if (tok->str() != "return")
enum { NO, INT, PTR, PTRDIFF } type = NO; continue;
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 (retPointer && (type == INT || type == PTRDIFF)) if (!tok->astOperand1() || tok->astOperand1()->isNumber())
returnIntegerError(tok); continue;
else if (!retPointer && type == PTR)
returnPointerError(tok); 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) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) { for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "[;{}] %var% = %name%")) { if (tok->str() != "=")
const Token* tok2 = tok->tokAt(3); continue;
while (Token::Match(tok2->next(), ".|::"))
tok2 = tok2->tokAt(2);
if (!Token::Match(tok2, "%var% ;|+"))
continue;
const Variable *var1(tok->next()->variable()); const ValueType *lhstype = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
const Variable *var2(tok2->variable()); const ValueType *rhstype = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr;
if (!lhstype || !rhstype)
continue;
if (isaddr(var1) && isint(var2) && tok2->strAt(1) != "+") // Assign integer to pointer..
assignmentIntegerToAddressError(tok->next()); 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()) { // Assign pointer to integer..
// assigning address => warning if (rhstype->pointer >= 1U &&
// some trivial addition => warning lhstype->pointer == 0U &&
if (Token::Match(tok2->next(), "+ %any% !!;")) lhstype->originalTypeName.empty() &&
continue; lhstype->type == ValueType::Type::INT)
assignmentAddressToIntegerError(tok);
assignmentAddressToIntegerError(tok->next());
}
}
} }
} }
} }

View File

@ -138,7 +138,7 @@ private:
" int x = 10;\n" " int x = 10;\n"
" int *a = x * x;\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" check("void foo(int *start, int *end) {\n"
" int len;\n" " int len;\n"