From a500f6f703d82f2cb166c143cfe85a393369bffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 8 Oct 2015 19:50:10 +0200 Subject: [PATCH] Improved handling of 'long double' and address-of in ValueType. Removed Tokenizer::simplifyFloatCasts() to handle float casts better. --- lib/checkio.cpp | 2 +- lib/checkother.cpp | 2 +- lib/symboldatabase.cpp | 20 +++++++++++++++++--- lib/symboldatabase.h | 2 +- lib/tokenize.cpp | 16 ---------------- test/testsymboldatabase.cpp | 5 +++++ test/testtokenize.cpp | 17 ----------------- 7 files changed, 25 insertions(+), 39 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 629b6939a..e241af590 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -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); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f1fc764f9..a56fb8c40 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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())) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2b504027e..426345149 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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)) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 03c53408a..61332ce66 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 691da017a..97b365026 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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()) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fc4b31a09..d95accf68 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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\"")); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0b9adbfdc..359e7a567 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -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 };"));