Fixed #8833 (false negative: No 'return' statement in non-void function causes undefined behavior.) (#1463)
This commit is contained in:
parent
977fdd88a9
commit
2275f05f65
|
@ -1345,7 +1345,7 @@ void CheckClass::operatorEqRetRefThis()
|
|||
for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
||||
if (func->type == Function::eOperatorEqual && func->hasBody()) {
|
||||
// make sure return signature is correct
|
||||
if (Token::Match(func->retDef, "%type% &") && func->retDef->str() == scope->className) {
|
||||
if (func->retType == func->nestedIn->definedType && func->tokenDef->strAt(-1) == "&") {
|
||||
checkReturnPtrThis(scope, &(*func), func->functionScope->bodyStart, func->functionScope->bodyEnd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1991,7 +1991,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
|
|||
}
|
||||
|
||||
// remove class name
|
||||
else if (arg_path_length > 2) {
|
||||
else if (arg_path_length > 2 && first->strAt(1) != second->strAt(1)) {
|
||||
std::string short_path = path;
|
||||
unsigned int short_path_length = arg_path_length;
|
||||
|
||||
|
@ -3297,7 +3297,6 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
|
|||
// skip over qualification if present
|
||||
nameTok = skipScopeIdentifiers(nameTok);
|
||||
if (nameTok && ((type == Scope::eEnum && Token::Match(nameTok, ":|{")) || nameTok->str() != "{")) // anonymous and unnamed structs/unions don't have a name
|
||||
|
||||
className = nameTok->str();
|
||||
}
|
||||
|
||||
|
|
|
@ -1237,6 +1237,90 @@ private:
|
|||
"};\n"
|
||||
"A::B & A::B::operator=(const A::B &b) { return b; }");
|
||||
ASSERT_EQUALS("[test.cpp:10]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class B;\n"
|
||||
"};\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" B & operator=(const B & b) { return b; }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class B;\n"
|
||||
"};\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" B & operator=(const B &);\n"
|
||||
"};\n"
|
||||
"A::B & A::B::operator=(const A::B & b) { return b; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class B;\n"
|
||||
"};\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" A::B & operator=(const A::B & b) { return b; }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class B;\n"
|
||||
"};\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" A::B & operator=(const A::B &);\n"
|
||||
"};\n"
|
||||
"A::B & A::B::operator=(const A::B & b) { return b; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace A {\n"
|
||||
" class B;\n"
|
||||
"}\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" B & operator=(const B & b) { return b; }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace A {\n"
|
||||
" class B;\n"
|
||||
"}\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" B & operator=(const B &);\n"
|
||||
"};\n"
|
||||
"A::B & A::B::operator=(const A::B & b) { return b; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace A {\n"
|
||||
" class B;\n"
|
||||
"}\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" A::B & operator=(const A::B & b) { return b; }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace A {\n"
|
||||
" class B;\n"
|
||||
"}\n"
|
||||
"class A::B\n"
|
||||
"{\n"
|
||||
" A::B & operator=(const A::B &);\n"
|
||||
"};\n"
|
||||
"A::B & A::B::operator=(const A::B & b) { return b; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
|
||||
}
|
||||
|
||||
void operatorEqRetRefThis2() {
|
||||
|
@ -1244,7 +1328,7 @@ private:
|
|||
checkOpertorEqRetRefThis(
|
||||
"class szp\n"
|
||||
"{\n"
|
||||
" szp &operator =(int *other) {};\n"
|
||||
" szp &operator =(int *other) {}\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
|
@ -1255,6 +1339,90 @@ private:
|
|||
"};\n"
|
||||
"szp &szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace NS {\n"
|
||||
" class szp;\n"
|
||||
"}\n"
|
||||
"class NS::szp\n"
|
||||
"{\n"
|
||||
" szp &operator =(int *other) {}\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace NS {\n"
|
||||
" class szp;\n"
|
||||
"}\n"
|
||||
"class NS::szp\n"
|
||||
"{\n"
|
||||
" szp &operator =(int *other);\n"
|
||||
"};\n"
|
||||
"NS::szp &NS::szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace NS {\n"
|
||||
" class szp;\n"
|
||||
"}\n"
|
||||
"class NS::szp\n"
|
||||
"{\n"
|
||||
" NS::szp &operator =(int *other) {}\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"namespace NS {\n"
|
||||
" class szp;\n"
|
||||
"}\n"
|
||||
"class NS::szp\n"
|
||||
"{\n"
|
||||
" NS::szp &operator =(int *other);\n"
|
||||
"};\n"
|
||||
"NS::szp &NS::szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class szp;\n"
|
||||
"};\n"
|
||||
"class A::szp\n"
|
||||
"{\n"
|
||||
" szp &operator =(int *other) {}\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class szp;\n"
|
||||
"};\n"
|
||||
"class A::szp\n"
|
||||
"{\n"
|
||||
" szp &operator =(int *other);\n"
|
||||
"};\n"
|
||||
"A::szp &A::szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class szp;\n"
|
||||
"};\n"
|
||||
"class A::szp\n"
|
||||
"{\n"
|
||||
" A::szp &operator =(int *other) {}\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
|
||||
checkOpertorEqRetRefThis(
|
||||
"class A {\n"
|
||||
" class szp;\n"
|
||||
"};\n"
|
||||
"class A::szp\n"
|
||||
"{\n"
|
||||
" A::szp &operator =(int *other);\n"
|
||||
"};\n"
|
||||
"A::szp &A::szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) No 'return' statement in non-void function causes undefined behavior.\n", errout.str());
|
||||
}
|
||||
|
||||
void operatorEqRetRefThis3() {
|
||||
|
|
Loading…
Reference in New Issue