Fixed #2007 (False positive: member variable not initialized (Borland C++ property))

This commit is contained in:
Daniel Marjamäki 2010-09-01 18:10:12 +02:00
parent 4153b7d24b
commit eb74bfc15a
4 changed files with 71 additions and 25 deletions

View File

@ -1972,6 +1972,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// remove Microsoft MFC..
simplifyMicrosoftMFC();
// remove Borland stuff..
simplifyBorland();
// typedef..
simplifyTypedef();
@ -8304,5 +8307,55 @@ void Tokenizer::simplifyMicrosoftMFC()
}
// Remove Borland code
void Tokenizer::simplifyBorland()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (Token::Match(tok, "( __closure * %var% )"))
{
tok->deleteNext();
}
}
// I think that these classes are always declared at the outer scope
// I save some time by ignoring inner classes.
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (tok->str() == "{")
tok = tok->link();
if (Token::Match(tok, "class %var% :|{"))
{
unsigned int indentlevel = 0;
for (Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if (tok2->str() == "{")
{
if (indentlevel == 0)
indentlevel = 1;
else
tok2 = tok2->link();
}
else if (tok2->str() == "}")
{
break;
}
else if (tok2->str() == "__property" &&
Token::Match(tok2->previous(), ";|{|}|protected:|public:|__published:"))
{
while (tok2 && !Token::Match(tok2, "{|;"))
tok2->deleteThis();
if (Token::simpleMatch(tok2, "{"))
{
Token::eraseTokens(tok2, tok2->link());
tok2->deleteThis();
tok2->deleteThis();
}
}
}
}
}
}

View File

@ -478,6 +478,11 @@ public:
*/
void simplifyMicrosoftMFC();
/**
* Remove Borland code
*/
void simplifyBorland();
/**
* This will return a short name describing function parameters
* e.g. parameters: (int a, char b) should get name "int,char,".

View File

@ -73,7 +73,6 @@ private:
TEST_CASE(uninitVarHeader2); // Class is defined in header
TEST_CASE(uninitVarHeader3); // Class is defined in header
TEST_CASE(uninitVarPublished); // Borland C++: Variables in the published section are auto-initialized
TEST_CASE(uninitProperty); // Borland C++: No FP for properties
TEST_CASE(uninitOperator); // No FP about uninitialized 'operator[]'
TEST_CASE(uninitFunction1); // No FP when initialized in function
TEST_CASE(uninitFunction2); // No FP when initialized in function
@ -1995,30 +1994,6 @@ private:
" Fred() { }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkUninitVar("class Fred\n"
"{\n"
"__published:\n"
" int * i_;\n"
" __property int * i = {read=i_, write=i_};\n"
"public:\n"
" Fred() { i_ = 0; }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
// Borland C++: No FP for properties
void uninitProperty()
{
checkUninitVar("class Fred\n"
"{\n"
"private:\n"
" int * i_;\n"
"public:\n"
" Fred() { i_ = 0; }\n"
" __property int * i = {read=i_, write=i_};\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void uninitOperator()

View File

@ -259,6 +259,8 @@ private:
TEST_CASE(microsoftMFC);
TEST_CASE(borland);
TEST_CASE(sql);
}
@ -4613,6 +4615,17 @@ private:
ASSERT_EQUALS("class MyDialog : public CDialog { private: CString text ; } ;", tokenizeAndStringify(code4,false));
}
void borland()
{
// __closure
ASSERT_EQUALS("int * a ;",
tokenizeAndStringify("int (__closure *a)();", false));
// __property
ASSERT_EQUALS("class Fred { } ;",
tokenizeAndStringify("class Fred { __property int x = { } };", false));
}
void sql()
{
// Oracle PRO*C extensions for inline SQL. Just replace the SQL with "asm()" to fix wrong error messages