ValueType: Handling constness
This commit is contained in:
parent
b7f2f826a4
commit
604a9acb48
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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\""));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue