Suppress operatorEqVarError for known non-copyable types (#3869)

* Fix FP operatorEqVarError with class hierarchy

* Suppress operatorEqVarError for std::mutex

* Add test, non-copyable Qt types

* Update cppcheck-cfg.rng
This commit is contained in:
chrchr-github 2022-03-03 09:41:26 +01:00 committed by GitHub
parent 915ae4b845
commit 8a7992c6ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 1 deletions

View File

@ -534,6 +534,18 @@
</choice> </choice>
</zeroOrMore> </zeroOrMore>
</element> </element>
<element name="operatorEqVarError">
<zeroOrMore>
<choice>
<element name="check">
<ref name="DATA-EXTNAME"/>
</element>
<element name="suppress">
<ref name="DATA-EXTNAME"/>
</element>
</choice>
</zeroOrMore>
</element>
</optional> </optional>
</element> </element>

View File

@ -5109,6 +5109,12 @@
<suppress>QApplication</suppress> <suppress>QApplication</suppress>
<suppress>QMutexLocker</suppress> <suppress>QMutexLocker</suppress>
</unusedvar> </unusedvar>
<operatorEqVarError>
<suppress>QMutex</suppress>
<suppress>QRecursiveMutex</suppress>
<suppress>QSemaphore</suppress>
<suppress>QReadWriteLock</suppress>
</operatorEqVarError>
</type-checks> </type-checks>
<!-- Treat QStringList as QList<QString> since we can't remove the template parameter when we inherit. --> <!-- Treat QStringList as QList<QString> since we can't remove the template parameter when we inherit. -->
<define name="QStringList" value="QList&lt;QString&gt;"/> <define name="QStringList" value="QList&lt;QString&gt;"/>

View File

@ -8390,6 +8390,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
<suppress>std::basic_ofstream</suppress> <suppress>std::basic_ofstream</suppress>
<check>std::pair</check> <check>std::pair</check>
</unusedvar> </unusedvar>
<operatorEqVarError>
<suppress>std::mutex</suppress>
<suppress>std::recursive_mutex</suppress>
</operatorEqVarError>
</type-checks> </type-checks>
<podtype name="char8_t,std::char8_t" sign="u" size="1"/> <podtype name="char8_t,std::char8_t" sign="u" size="1"/>
<podtype name="char16_t,std::char16_t" sign="u" size="2"/> <podtype name="char16_t,std::char16_t" sign="u" size="2"/>

View File

@ -275,7 +275,7 @@ void CheckClass::constructors()
} }
} }
if (classNameUsed) if (classNameUsed && mSettings->library.getTypeCheck("operatorEqVarError", var.getTypeName()) != Library::TypeCheck::suppress)
operatorEqVarError(func.token, scope->className, var.name(), missingCopy); operatorEqVarError(func.token, scope->className, var.name(), missingCopy);
} else if (func.access != AccessControl::Private || mSettings->standards.cpp >= Standards::CPP11) { } else if (func.access != AccessControl::Private || mSettings->standards.cpp >= Standards::CPP11) {
// If constructor is not in scope then we maybe using a constructor from a different template specialization // If constructor is not in scope then we maybe using a constructor from a different template specialization

View File

@ -1854,6 +1854,17 @@ private:
"void Fred::operator=(const Fred &f)\n" "void Fred::operator=(const Fred &f)\n"
"{ }", true); "{ }", true);
ASSERT_EQUALS("[test.cpp:13]: (warning, inconclusive) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='.\n", errout.str()); ASSERT_EQUALS("[test.cpp:13]: (warning, inconclusive) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='.\n", errout.str());
Settings s;
s.certainty.setEnabled(Certainty::inconclusive, true);
s.severity.enable(Severity::style);
s.severity.enable(Severity::warning);
LOAD_LIB_2(s.library, "std.cfg");
check("struct S {\n"
" S& operator=(const S& s) { return *this; }\n"
" std::mutex m;\n"
"};\n", s);
ASSERT_EQUALS("", errout.str());
} }
void uninitVar1() { void uninitVar1() {