Fix false positives when class might inherit from VCL TObject class
This commit is contained in:
parent
5dae162780
commit
03445c01c1
|
@ -79,6 +79,28 @@ static bool isVariableCopyNeeded(const Variable &var)
|
||||||
(var.valueType() && var.valueType()->type >= ValueType::Type::CHAR);
|
(var.valueType() && var.valueType()->type >= ValueType::Type::CHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isVcl(const Settings *settings)
|
||||||
|
{
|
||||||
|
for (const std::string &library: settings->libraries) {
|
||||||
|
if (library == "vcl")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isVclTypeInit(const Type *type)
|
||||||
|
{
|
||||||
|
if (!type)
|
||||||
|
return false;
|
||||||
|
for (const Type::BaseInfo &baseInfo: type->derivedFrom) {
|
||||||
|
if (!baseInfo.type)
|
||||||
|
return true;
|
||||||
|
if (isVclTypeInit(baseInfo.type))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
|
@ -101,6 +123,9 @@ void CheckClass::constructors()
|
||||||
|
|
||||||
const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
|
const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
|
||||||
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
|
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
|
||||||
|
if (isVcl(mSettings) && isVclTypeInit(scope->definedType))
|
||||||
|
continue;
|
||||||
|
|
||||||
const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">");
|
const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">");
|
||||||
|
|
||||||
bool usedInUnion = false;
|
bool usedInUnion = false;
|
||||||
|
|
|
@ -47,6 +47,20 @@ private:
|
||||||
checkClass.constructors();
|
checkClass.constructors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check(const char code[], const Settings &s) {
|
||||||
|
// Clear the error buffer..
|
||||||
|
errout.str("");
|
||||||
|
|
||||||
|
// Tokenize..
|
||||||
|
Tokenizer tokenizer(&s, this);
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
|
||||||
|
// Check class constructors..
|
||||||
|
CheckClass checkClass(&tokenizer, &s, this);
|
||||||
|
checkClass.constructors();
|
||||||
|
}
|
||||||
|
|
||||||
void run() OVERRIDE {
|
void run() OVERRIDE {
|
||||||
settings.severity.enable(Severity::style);
|
settings.severity.enable(Severity::style);
|
||||||
settings.severity.enable(Severity::warning);
|
settings.severity.enable(Severity::warning);
|
||||||
|
@ -176,6 +190,7 @@ private:
|
||||||
TEST_CASE(privateCtor2); // If constructor is private..
|
TEST_CASE(privateCtor2); // If constructor is private..
|
||||||
TEST_CASE(function); // Function is not variable
|
TEST_CASE(function); // Function is not variable
|
||||||
TEST_CASE(uninitVarPublished); // Borland C++: Variables in the published section are auto-initialized
|
TEST_CASE(uninitVarPublished); // Borland C++: Variables in the published section are auto-initialized
|
||||||
|
TEST_CASE(uninitVarInheritClassInit); // Borland C++: if class inherits from TObject, all variables are initialized
|
||||||
TEST_CASE(uninitOperator); // No FP about uninitialized 'operator[]'
|
TEST_CASE(uninitOperator); // No FP about uninitialized 'operator[]'
|
||||||
TEST_CASE(uninitFunction1); // No FP when initialized in function
|
TEST_CASE(uninitFunction1); // No FP when initialized in function
|
||||||
TEST_CASE(uninitFunction2); // No FP when initialized in function
|
TEST_CASE(uninitFunction2); // No FP when initialized in function
|
||||||
|
@ -3163,6 +3178,20 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uninitVarInheritClassInit() {
|
||||||
|
Settings s;
|
||||||
|
s.libraries.emplace_back("vcl");
|
||||||
|
|
||||||
|
check("class Fred: public TObject\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" Fred() { }\n"
|
||||||
|
"private:\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};", s);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void uninitOperator() {
|
void uninitOperator() {
|
||||||
check("class Fred\n"
|
check("class Fred\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue