ValueType: Added support for static member variables and simplified code

This commit is contained in:
PKEuS 2016-02-04 20:49:13 +01:00
parent b801386ac8
commit cae19cadd3
3 changed files with 36 additions and 25 deletions

View File

@ -3676,12 +3676,15 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
Token *parent = const_cast<Token *>(tok->astParent()); Token *parent = const_cast<Token *>(tok->astParent());
if (!parent || parent->valueType()) if (!parent || parent->valueType())
return; return;
if (!parent->astOperand1() || !parent->astOperand1()->valueType()) if (!parent->astOperand1())
return; return;
if (Token::Match(parent, "<<|>>")) { const ValueType *vt1 = parent->astOperand1() ? parent->astOperand1()->valueType() : nullptr;
if (!cpp || (parent->astOperand2() && parent->astOperand2()->valueType() && parent->astOperand2()->valueType()->isIntegral())) const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr;
setValueType(parent, *parent->astOperand1()->valueType(), cpp, defaultSignedness);
if (vt1 && Token::Match(parent, "<<|>>")) {
if (!cpp || (vt2 && vt2->isIntegral()))
setValueType(parent, *vt1, cpp, defaultSignedness);
return; return;
} }
@ -3706,26 +3709,31 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
return; return;
} }
if (parent->str() == "." && if ((parent->str() == "." || parent->str() == "::") &&
valuetype.typeScope && parent->astOperand2() && parent->astOperand2()->isName()) {
parent->astOperand2() && parent->astOperand2()->isName() && !parent->astOperand2()->valueType()) { const Variable* var = parent->astOperand2()->variable();
const std::string &name = parent->astOperand2()->str(); if (!var && valuetype.typeScope && vt1) {
const Scope *typeScope = parent->astOperand1()->valueType()->typeScope; const std::string &name = parent->astOperand2()->str();
if (!typeScope) const Scope *typeScope = vt1->typeScope;
return; if (!typeScope)
for (std::list<Variable>::const_iterator it = typeScope->varlist.begin(); it != typeScope->varlist.end(); ++it) {
const Variable &var = *it;
if (var.nameToken()->str() == name) {
setValueType(parent, var, cpp, defaultSignedness);
return; return;
for (std::list<Variable>::const_iterator it = typeScope->varlist.begin(); it != typeScope->varlist.end(); ++it) {
if (it->nameToken()->str() == name) {
var = &*it;
break;
}
} }
} }
if (var)
setValueType(parent, *var, cpp, defaultSignedness);
return;
} }
if (parent->astOperand2() && !parent->astOperand2()->valueType()) if (!vt1)
return; return;
const ValueType *vt1 = parent->astOperand1()->valueType(); if (parent->astOperand2() && !vt2)
const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr; return;
if (parent->isArithmeticalOp() && vt2) { if (parent->isArithmeticalOp() && vt2) {
if (vt1->pointer != 0U && vt2->pointer == 0U) { if (vt1->pointer != 0U && vt2->pointer == 0U) {
setValueType(parent, *vt1, cpp, defaultSignedness); setValueType(parent, *vt1, cpp, defaultSignedness);

View File

@ -1648,11 +1648,11 @@ private:
" f[0].d, f[0].baz.i, f[0].bar[0].i);\n" " f[0].d, f[0].baz.i, f[0].bar[0].i);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:13]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'double'.\n" ASSERT_EQUALS("[test.cpp:13]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'double'.\n"
"[test.cpp:13]: (warning) %f in format string (no. 2) requires 'double' but the argument type is 'int'.\n" "[test.cpp:13]: (warning) %f in format string (no. 2) requires 'double' but the argument type is 'signed int'.\n"
"[test.cpp:13]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'signed int'.\n" "[test.cpp:13]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'signed int'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 4) requires 'int' but the argument type is 'double'.\n" "[test.cpp:13]: (warning) %d in format string (no. 4) requires 'int' but the argument type is 'double'.\n"
"[test.cpp:13]: (warning) %f in format string (no. 5) requires 'double' but the argument type is 'int'.\n" "[test.cpp:13]: (warning) %f in format string (no. 5) requires 'double' but the argument type is 'signed int'.\n"
"[test.cpp:13]: (warning) %f in format string (no. 6) requires 'double' but the argument type is 'int'.\n", errout.str()); "[test.cpp:13]: (warning) %f in format string (no. 6) requires 'double' but the argument type is 'signed int'.\n", errout.str());
check("short f() { return 0; }\n" check("short f() { return 0; }\n"
"void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); "void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }");

View File

@ -49,6 +49,7 @@ private:
const Token* t; const Token* t;
bool found; bool found;
Settings settings; Settings settings;
Settings settings2;
void reset() { void reset() {
vartok = nullptr; vartok = nullptr;
@ -96,6 +97,7 @@ private:
void run() { void run() {
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
settings2.platform(Settings::Unspecified);
TEST_CASE(array); TEST_CASE(array);
TEST_CASE(stlarray); TEST_CASE(stlarray);
@ -3118,12 +3120,10 @@ private:
} }
std::string typeOf(const char code[], const char str[], const char filename[] = "test.cpp") { std::string typeOf(const char code[], const char str[], const char filename[] = "test.cpp") {
Settings s; Tokenizer tokenizer(&settings2, this);
s.platform(Settings::Unspecified);
Tokenizer tokenizer(&s, this);
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, filename); tokenizer.tokenize(istr, filename);
const Token * const tok = Token::findsimplematch(tokenizer.tokens(),str); const Token * const tok = Token::findsimplematch(tokenizer.tokens(), str);
return tok->valueType() ? tok->valueType()->str() : std::string(); return tok->valueType() ? tok->valueType()->str() : std::string();
} }
@ -3226,6 +3226,9 @@ private:
// struct member.. // struct member..
ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } ab; x = ab.a;", ".")); ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } ab; x = ab.a;", "."));
ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } *ab; x = ab[1].a;", ".")); ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } *ab; x = ab[1].a;", "."));
// Static members
ASSERT_EQUALS("signed int", typeOf("struct AB { static int a; }; x = AB::a;", "::"));
} }
}; };