ValueType: Handling constness

This commit is contained in:
Daniel Marjamäki 2015-10-07 19:08:26 +02:00
parent b7f2f826a4
commit 604a9acb48
5 changed files with 58 additions and 43 deletions

View File

@ -1366,10 +1366,15 @@ 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%|%num%|%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) {
tempToken = new Token(0);
typeToken = tempToken = new Token(0);
if (valuetype->constness & 1) {
tempToken->str("const");
tempToken->insertToken("a");
tempToken = tempToken->next();
}
if (valuetype->pointer == 0U && valuetype->type <= ValueType::INT)
tempToken->str("int");
else if (valuetype->type == ValueType::BOOL)
@ -1397,7 +1402,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings,
}
for (unsigned int p = 0; p < valuetype->pointer; p++)
tempToken->insertToken("*");
typeToken = tempToken;
tempToken = const_cast<Token*>(typeToken);
return;
}
}

View File

@ -3650,9 +3650,9 @@ bool SymbolDatabase::isReservedName(const std::string& iName) const
return (c_keywords.find(iName) != c_keywords.cend()) || (isCPP() && (cpp_keywords.find(iName) != cpp_keywords.cend()));
}
static void setValueType(Token *tok, ValueType::Sign sign, ValueType::Type type, unsigned int pointer)
static void setValueType(Token *tok, ValueType::Sign sign, ValueType::Type type, unsigned int pointer, unsigned int constness = 0U)
{
tok->setValueType(new ValueType(sign,type,pointer));
tok->setValueType(new ValueType(sign,type,pointer,constness));
Token *parent = const_cast<Token *>(tok->astParent());
if (!parent || parent->valueType())
return;
@ -3660,11 +3660,11 @@ static void setValueType(Token *tok, ValueType::Sign sign, ValueType::Type type,
return;
if (parent->str() == "[" && pointer > 0U) {
setValueType(parent, sign, type, pointer - 1U);
setValueType(parent, sign, type, pointer - 1U, constness >> 1);
return;
}
if (parent->str() == "*" && !parent->astOperand2() && pointer > 0U) {
setValueType(parent, sign, type, pointer - 1U);
setValueType(parent, sign, type, pointer - 1U, constness >> 1);
return;
}
@ -3674,17 +3674,17 @@ static void setValueType(Token *tok, ValueType::Sign sign, ValueType::Type type,
const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr;
if (parent->isArithmeticalOp() && vt2) {
if (vt1->pointer != 0U && vt2->pointer == 0U) {
setValueType(parent, vt1->sign, vt1->type, vt1->pointer);
setValueType(parent, vt1->sign, vt1->type, vt1->pointer, vt1->constness);
return;
}
if (vt1->pointer == 0U && vt2->pointer != 0U) {
setValueType(parent, vt2->sign, vt2->type, vt2->pointer);
setValueType(parent, vt2->sign, vt2->type, vt2->pointer, vt2->constness);
return;
}
if (vt1->pointer != 0U) { // result is pointer diff
setValueType(parent, ValueType::Sign::UNSIGNED, ValueType::Type::INT, 0U);
setValueType(parent, ValueType::Sign::UNSIGNED, ValueType::Type::INT, 0U, 0U);
return;
}
@ -3789,7 +3789,7 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens)
else if (tok->tokType() == Token::eChar)
::setValueType(tok, ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 0U);
else if (tok->tokType() == Token::eString)
::setValueType(tok, ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U);
::setValueType(tok, ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U, 1U);
else if (tok->str() == "(") {
// cast
if (!tok->astOperand2() && Token::Match(tok, "( %name%")) {
@ -3810,28 +3810,33 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens)
std::string ValueType::str() const
{
std::string ret;
if (constness & 1)
ret = " const";
if (isIntegral()) {
if (sign == SIGNED)
ret = "signed ";
ret += " signed";
else if (sign == UNSIGNED)
ret = "unsigned ";
ret += " unsigned";
if (type == BOOL)
ret += "bool";
ret += " bool";
else if (type == CHAR)
ret += "char";
ret += " char";
else if (type == SHORT)
ret += "short";
ret += " short";
else if (type == INT)
ret += "int";
ret += " int";
else if (type == LONG)
ret += "long";
ret += " long";
else if (type == LONGLONG)
ret += "long long";
ret += " long long";
} else if (type == FLOAT)
ret = "float";
ret = " float";
else if (type == DOUBLE)
ret = "double";
for (unsigned int p = 0; p < pointer; p++)
ret += "*";
return ret;
ret = " double";
for (unsigned int p = 0; p < pointer; p++) {
ret += " *";
if (constness & (2 << p))
ret += " const";
}
return ret.substr(1);
}

View File

@ -1044,9 +1044,11 @@ public:
enum Sign {UNKNOWN_SIGN, SIGNED, UNSIGNED} sign;
enum Type {UNKNOWN_TYPE, NONSTD, BOOL, CHAR, SHORT, INT, LONG, LONGLONG, FLOAT, DOUBLE} type;
unsigned int pointer; // 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
unsigned int constness; // bit 0=data, bit 1=*, bit 2=**
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U) {}
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p) {}
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U) {}
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U) {}
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c) {}
bool isIntegral() const {
return (type >= ValueType::Type::BOOL && type <= ValueType::Type::LONGLONG);

View File

@ -2317,11 +2317,11 @@ private:
void testPrintfArgument() {
check("void foo() {\n"
" printf(\"%u\");\n"
" printf(\"%u%s\", 123);\n"
" printf(\"%u%s%d\", 0, bar());\n"
" printf(\"%u%%%s%d\", 0, bar());\n"
" printf(\"%udfd%%dfa%s%d\", 0, bar());\n"
" printf(\"%i\");\n"
" printf(\"%i%s\", 123);\n"
" printf(\"%i%s%d\", 0, bar());\n"
" printf(\"%i%%%s%d\", 0, bar());\n"
" printf(\"%idfd%%dfa%s%d\", 0, bar());\n"
" fprintf(stderr,\"%u%s\");\n"
" snprintf(str,10,\"%u%s\");\n"
" sprintf(string1, \"%-*.*s\", 32, string2);\n" // #3364
@ -2339,28 +2339,28 @@ private:
check("void foo(char *str) {\n"
" printf(\"\", 0);\n"
" printf(\"%u\", 123, bar());\n"
" printf(\"%u%s\", 0, bar(), 43123);\n"
" printf(\"%i\", 123, bar());\n"
" printf(\"%i%s\", 0, bar(), 43123);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) printf format string requires 0 parameters but 1 is given.\n"
"[test.cpp:3]: (warning) printf format string requires 1 parameter but 2 are given.\n"
"[test.cpp:4]: (warning) printf format string requires 2 parameters but 3 are given.\n", errout.str());
check("void foo() {\n" // swprintf exists as MSVC extension and as standard function: #4790
" swprintf(string1, L\"%u\", 32, string2);\n" // MSVC implementation
" swprintf(string1, L\"%i\", 32, string2);\n" // MSVC implementation
" swprintf(string1, L\"%s%s\", L\"a\", string2);\n" // MSVC implementation
" swprintf(string1, 6, L\"%u\", 32, string2);\n" // Standard implementation
" swprintf(string1, 6, L\"%u%s\", 32, string2);\n" // Standard implementation
" swprintf(string1, 6, L\"%i\", 32, string2);\n" // Standard implementation
" swprintf(string1, 6, L\"%i%s\", 32, string2);\n" // Standard implementation
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) swprintf format string requires 1 parameter but 2 are given.\n"
"[test.cpp:4]: (warning) swprintf format string requires 1 parameter but 2 are given.\n", errout.str());
check("void foo(char *str) {\n"
" printf(\"%u\", 0);\n"
" printf(\"%u%s\", 123, bar());\n"
" printf(\"%u%s%d\", 0, bar(), 43123);\n"
" printf(\"%u%%%s%d\", 0, bar(), 43123);\n"
" printf(\"%udfd%%dfa%s%d\", 0, bar(), 43123);\n"
" printf(\"%i\", 0);\n"
" printf(\"%i%s\", 123, bar());\n"
" printf(\"%i%s%d\", 0, bar(), 43123);\n"
" printf(\"%i%%%s%d\", 0, bar(), 43123);\n"
" printf(\"%idfd%%dfa%s%d\", 0, bar(), 43123);\n"
" printf(\"%\"PRId64\"\n\", 123);\n"
" fprintf(stderr,\"%\"PRId64\"\n\", 123);\n"
" snprintf(str,10,\"%\"PRId64\"\n\", 123);\n"

View File

@ -2972,7 +2972,7 @@ private:
ASSERT_EQUALS("float", typeOf("1 + 2.3f", "+"));
// char *
ASSERT_EQUALS("char*", typeOf("\"hello\" + 1", "+"));
ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1", "+"));
ASSERT_EQUALS("char", typeOf("\"hello\"[1]", "["));
ASSERT_EQUALS("char", typeOf("*\"hello\"", "*"));
@ -2988,7 +2988,7 @@ private:
ASSERT_EQUALS("unsigned int", typeOf("unsigned int u1, u2; a = u1 * u2;", "u1 *"));
// array..
ASSERT_EQUALS("int*", typeOf("int x[10]; a = x + 1;", "+"));
ASSERT_EQUALS("int *", typeOf("int x[10]; a = x + 1;", "+"));
ASSERT_EQUALS("int", typeOf("int x[10]; a = x[0] + 1;", "+"));
// cast..
@ -2996,6 +2996,9 @@ 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;", "("));
// const..
ASSERT_EQUALS("const char *", typeOf("a = \"123\";", "\"123\""));
}
};