Fix issue 7372: False positive uninitMemberVar - on template specialization
This fixes the issue by skipping diagnostics when the symbols are incomplete in the constructor.
This commit is contained in:
parent
4a9176f83c
commit
cf3515ee61
|
@ -145,6 +145,13 @@ void CheckClass::constructors()
|
|||
if (!func.hasBody() || !(func.isConstructor() || func.type == Function::eOperatorEqual))
|
||||
continue;
|
||||
|
||||
// Bail: If initializer list is not recognized as a variable or type then skip since parsing is incomplete
|
||||
if (func.type == Function::eConstructor) {
|
||||
const Token *initList = func.constructorMemberInitialization();
|
||||
if (Token::Match(initList, ": %name% (") && initList->next()->tokType() == Token::eName)
|
||||
break;
|
||||
}
|
||||
|
||||
// Mark all variables not used
|
||||
clearAllVar(usage);
|
||||
|
||||
|
@ -218,6 +225,9 @@ void CheckClass::constructors()
|
|||
if (classNameUsed)
|
||||
operatorEqVarError(func.token, scope->className, var.name(), inconclusive);
|
||||
} else if (func.access != Private || mSettings->standards.cpp >= Standards::CPP11) {
|
||||
// If constructor is not in scope then we maybe using a oonstructor from a different template specialization
|
||||
if (!precedes(scope->bodyStart, func.tokenDef))
|
||||
continue;
|
||||
const Scope *varType = var.typeScope();
|
||||
if (!varType || varType->type != Scope::eUnion) {
|
||||
if (func.type == Function::eConstructor &&
|
||||
|
|
|
@ -194,6 +194,8 @@ private:
|
|||
TEST_CASE(uninitAssignmentWithOperator); // ticket #7429
|
||||
TEST_CASE(uninitCompoundAssignment); // ticket #7429
|
||||
TEST_CASE(uninitComparisonAssignment); // ticket #7429
|
||||
|
||||
TEST_CASE(uninitTemplate1); // ticket #7372
|
||||
}
|
||||
|
||||
|
||||
|
@ -2172,7 +2174,8 @@ private:
|
|||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor.\n", errout.str());
|
||||
|
||||
check("Object::MemFunc() {\n"
|
||||
check("struct copy_protected;\n"
|
||||
"Object::MemFunc() {\n"
|
||||
" class LocalClass : public copy_protected {\n"
|
||||
" public:\n"
|
||||
" LocalClass() : copy_protected(1), dataLength_(0) {}\n"
|
||||
|
@ -2180,9 +2183,12 @@ private:
|
|||
" double bitsInData_;\n"
|
||||
" } obj;\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor.\n", errout.str());
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:5]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor.\n",
|
||||
errout.str());
|
||||
|
||||
check("Object::MemFunc() {\n"
|
||||
check("struct copy_protected;\n"
|
||||
"Object::MemFunc() {\n"
|
||||
" class LocalClass : ::copy_protected {\n"
|
||||
" public:\n"
|
||||
" LocalClass() : copy_protected(1), dataLength_(0) {}\n"
|
||||
|
@ -2190,7 +2196,9 @@ private:
|
|||
" double bitsInData_;\n"
|
||||
" } obj;\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor.\n", errout.str());
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:5]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor.\n",
|
||||
errout.str());
|
||||
}
|
||||
|
||||
void uninitVar21() { // ticket #2947
|
||||
|
@ -3849,6 +3857,36 @@ private:
|
|||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void uninitTemplate1() {
|
||||
check("template <class A, class T> class C;\n"
|
||||
"template <class A>\n"
|
||||
"class C<A, void> {\n"
|
||||
" public:\n"
|
||||
" C() : b(0) { }\n"
|
||||
" C(A* a) : b(a) { }\n"
|
||||
" private:\n"
|
||||
" A* b;\n"
|
||||
"};\n"
|
||||
"template <class A, class T>\n"
|
||||
"class C {\n"
|
||||
" private:\n"
|
||||
" A* b;\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("template<class T> class A{};\n"
|
||||
"template<class T1, class T2> class B{};\n"
|
||||
"template<class T1, class T2>\n"
|
||||
"class A<B<T1, T2>> {\n"
|
||||
" public:\n"
|
||||
" A();\n"
|
||||
" bool m_value;\n"
|
||||
"};\n"
|
||||
"template<class T1, class T2>\n"
|
||||
"A<B<T1, T2>>::A() : m_value(false) {}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestConstructors)
|
||||
|
|
Loading…
Reference in New Issue