Improved handling of 'long double' and address-of in ValueType. Removed Tokenizer::simplifyFloatCasts() to handle float casts better.

This commit is contained in:
Daniel Marjamäki 2015-10-08 19:50:10 +02:00
parent 856e4c414d
commit a500f6f703
7 changed files with 25 additions and 39 deletions

View File

@ -1366,7 +1366,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings,
// Use AST type info
// TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type.
if (!Token::Match(tok, "%str%|%name% ,|)") && !Token::Match(tok, "%name% [|(|.|<|::|?")) {
if (!Token::Match(tok, "&| %str%|%name% ,|)") && !Token::Match(tok, "%name% [|(|.|<|::|?")) {
const ValueType *valuetype = tok->argumentType();
if (valuetype && valuetype->type >= ValueType::Type::BOOL) {
typeToken = tempToken = new Token(0);

View File

@ -1623,7 +1623,7 @@ void CheckOther::checkZeroDivision()
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (!Token::Match(tok, "[/%]") || !tok->astOperand1() || !tok->astOperand2())
continue;
if (!astIsIntegral(tok,false))
if (!tok->valueType() || !tok->valueType()->isIntegral())
continue;
if (tok->astOperand1()->isNumber()) {
if (MathLib::isFloat(tok->astOperand1()->str()))

View File

@ -3675,6 +3675,14 @@ static void setValueType(Token *tok, const ValueType &valuetype)
valuetype.originalTypeName));
return;
}
if (parent->str() == "&" && !parent->astOperand2()) {
setValueType(parent, ValueType(valuetype.sign,
valuetype.type,
valuetype.pointer + 1U,
valuetype.constness,
valuetype.originalTypeName));
return;
}
if (parent->astOperand2() && !parent->astOperand2()->valueType())
return;
@ -3696,6 +3704,10 @@ static void setValueType(Token *tok, const ValueType &valuetype)
return;
}
if (vt1->type == ValueType::Type::LONGDOUBLE || vt2->type == ValueType::Type::LONGDOUBLE) {
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::LONGDOUBLE, 0U));
return;
}
if (vt1->type == ValueType::Type::DOUBLE || vt2->type == ValueType::Type::DOUBLE) {
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::DOUBLE, 0U));
return;
@ -3760,7 +3772,7 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype)
else if (type->str() == "float")
valuetype->type = ValueType::Type::FLOAT;
else if (type->str() == "double")
valuetype->type = ValueType::Type::DOUBLE;
valuetype->type = type->isLong() ? ValueType::Type::LONGDOUBLE : ValueType::Type::DOUBLE;
else if (type->str() == "struct")
valuetype->type = ValueType::Type::NONSTD;
else if (type->str() == "*")
@ -3845,9 +3857,11 @@ std::string ValueType::str() const
else if (type == LONGLONG)
ret += " long long";
} else if (type == FLOAT)
ret = " float";
ret += " float";
else if (type == DOUBLE)
ret = " double";
ret += " double";
else if (type == LONGDOUBLE)
ret += " long double";
for (unsigned int p = 0; p < pointer; p++) {
ret += " *";
if (constness & (2 << p))

View File

@ -1042,7 +1042,7 @@ private:
class CPPCHECKLIB ValueType {
public:
enum Sign {UNKNOWN_SIGN, SIGNED, UNSIGNED} sign;
enum Type {UNKNOWN_TYPE, NONSTD, BOOL, CHAR, SHORT, INT, LONG, LONGLONG, FLOAT, DOUBLE} type;
enum Type {UNKNOWN_TYPE, NONSTD, BOOL, CHAR, SHORT, INT, LONG, LONGLONG, FLOAT, DOUBLE, LONGDOUBLE} type;
unsigned int pointer; // 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
unsigned int constness; // bit 0=data, bit 1=*, bit 2=**
std::string originalTypeName;

View File

@ -3467,9 +3467,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
simplifyVariableMultipleAssign();
// Simplify float casts (float)1 => 1.0
simplifyFloatCasts();
// Collapse operator name tokens into single token
// operator = => operator=
simplifyOperatorName();
@ -4842,19 +4839,6 @@ void Tokenizer::simplifyUndefinedSizeArray()
}
}
void Tokenizer::simplifyFloatCasts()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok->next(), "( float|double ) %num%") && MathLib::isInt(tok->strAt(4))) {
const bool isFloatType(tok->strAt(2) == "float");
tok->deleteNext(3);
tok = tok->next();
// in case of type 'float', add the corresponding suffix 'f'
tok->str(tok->str() + (isFloatType ? ".0f":".0"));
}
}
}
void Tokenizer::simplifyCasts()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {

View File

@ -2987,6 +2987,10 @@ private:
ASSERT_EQUALS("unsigned int", typeOf("unsigned int u1, u2; a = u1 + u2;", "u1 +"));
ASSERT_EQUALS("unsigned int", typeOf("unsigned int u1, u2; a = u1 * 2;", "u1 *"));
ASSERT_EQUALS("unsigned int", typeOf("unsigned int u1, u2; a = u1 * u2;", "u1 *"));
ASSERT_EQUALS("int *", typeOf("int x; a = &x;", "&"));
ASSERT_EQUALS("int *", typeOf("int x; a = &x;", "&"));
ASSERT_EQUALS("long double", typeOf("long double x; dostuff(x,1);", "x ,"));
ASSERT_EQUALS("long double *", typeOf("long double x; dostuff(&x,1);", "& x ,"));
// array..
ASSERT_EQUALS("int *", typeOf("int x[10]; a = x + 1;", "+"));
@ -2997,6 +3001,7 @@ private:
ASSERT_EQUALS("long", typeOf("a = (long)32;", "("));
ASSERT_EQUALS("long", typeOf("a = (long int)32;", "("));
ASSERT_EQUALS("long long", typeOf("a = (long long)32;", "("));
ASSERT_EQUALS("long double", typeOf("a = (long double)32;", "("));
// const..
ASSERT_EQUALS("const char *", typeOf("a = \"123\";", "\"123\""));

View File

@ -95,8 +95,6 @@ private:
TEST_CASE(removeCast16); // #6278
TEST_CASE(removeCast17); // #6110 - don't remove any parentheses in 'a(b)(c)'
TEST_CASE(simplifyFloatCasts); // float casting a integer
TEST_CASE(inlineasm);
TEST_CASE(ifAddBraces1);
@ -986,21 +984,6 @@ private:
tokenizeAndStringify("if (a(b)(c) >= 3)", true));
}
void simplifyFloatCasts() { // float casting integers
// C-style casts
ASSERT_EQUALS("a = 1.0f ;", tokenizeAndStringify("a = (float)1;"));
ASSERT_EQUALS("a = 1.0f ;", tokenizeAndStringify("a = ((float)1);"));
ASSERT_EQUALS("a = 291.0f ;", tokenizeAndStringify("a = ((float)0x123);"));
ASSERT_EQUALS("a = 1.0 ;", tokenizeAndStringify("a = (double)1;"));
ASSERT_EQUALS("a = 1.0 ;", tokenizeAndStringify("a = ((double)1);"));
ASSERT_EQUALS("a = 291.0 ;", tokenizeAndStringify("a = ((double)0x123);"));
ASSERT_EQUALS("a = 1.0 ;", tokenizeAndStringify("a = (long double)1;"));
ASSERT_EQUALS("a = 1.0 ;", tokenizeAndStringify("a = ((long double)1);"));
ASSERT_EQUALS("a = 291.0 ;", tokenizeAndStringify("a = ((long double)0x123);"));
}
void inlineasm() {
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));