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());
if (!parent || parent->valueType())
return;
if (!parent->astOperand1() || !parent->astOperand1()->valueType())
if (!parent->astOperand1())
return;
if (Token::Match(parent, "<<|>>")) {
if (!cpp || (parent->astOperand2() && parent->astOperand2()->valueType() && parent->astOperand2()->valueType()->isIntegral()))
setValueType(parent, *parent->astOperand1()->valueType(), cpp, defaultSignedness);
const ValueType *vt1 = parent->astOperand1() ? parent->astOperand1()->valueType() : nullptr;
const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr;
if (vt1 && Token::Match(parent, "<<|>>")) {
if (!cpp || (vt2 && vt2->isIntegral()))
setValueType(parent, *vt1, cpp, defaultSignedness);
return;
}
@ -3706,26 +3709,31 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
return;
}
if (parent->str() == "." &&
valuetype.typeScope &&
parent->astOperand2() && parent->astOperand2()->isName() && !parent->astOperand2()->valueType()) {
const std::string &name = parent->astOperand2()->str();
const Scope *typeScope = parent->astOperand1()->valueType()->typeScope;
if (!typeScope)
return;
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);
if ((parent->str() == "." || parent->str() == "::") &&
parent->astOperand2() && parent->astOperand2()->isName()) {
const Variable* var = parent->astOperand2()->variable();
if (!var && valuetype.typeScope && vt1) {
const std::string &name = parent->astOperand2()->str();
const Scope *typeScope = vt1->typeScope;
if (!typeScope)
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;
const ValueType *vt1 = parent->astOperand1()->valueType();
const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr;
if (parent->astOperand2() && !vt2)
return;
if (parent->isArithmeticalOp() && vt2) {
if (vt1->pointer != 0U && vt2->pointer == 0U) {
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"
"}");
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) %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. 6) requires 'double' but the argument type is 'int'.\n", errout.str());
"[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 'signed int'.\n", errout.str());
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()); }");

View File

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