Fix #9128 (FP in return non bool with class declared in function) (#1830)

Also break up the tests to smaller tests.
This commit is contained in:
Rikard Falkeborn 2019-05-14 08:56:28 +02:00 committed by Daniel Marjamäki
parent fd416eadce
commit dc0e8c214e
2 changed files with 53 additions and 8 deletions

View File

@ -473,6 +473,8 @@ void CheckBool::returnValueOfFunctionReturningBool(void)
const Token* tok2 = findLambdaEndToken(tok); const Token* tok2 = findLambdaEndToken(tok);
if (tok2) if (tok2)
tok = tok2; tok = tok2;
else if (tok->scope() && tok->scope()->isClassOrStruct())
tok = tok->scope()->bodyEnd;
else if (Token::simpleMatch(tok, "return") && tok->astOperand1() && else if (Token::simpleMatch(tok, "return") && tok->astOperand1() &&
(tok->astOperand1()->getValueGE(2, mSettings) || tok->astOperand1()->getValueLE(-1, mSettings)) && (tok->astOperand1()->getValueGE(2, mSettings) || tok->astOperand1()->getValueLE(-1, mSettings)) &&
!(tok->astOperand1()->astOperand1() && Token::Match(tok->astOperand1(), "&|%or%"))) !(tok->astOperand1()->astOperand1() && Token::Match(tok->astOperand1(), "&|%or%")))

View File

@ -66,6 +66,9 @@ private:
TEST_CASE(pointerArithBool1); TEST_CASE(pointerArithBool1);
TEST_CASE(returnNonBool); TEST_CASE(returnNonBool);
TEST_CASE(returnNonBoolLambda);
TEST_CASE(returnNonBoolLogicalOp);
TEST_CASE(returnNonBoolClass);
} }
void check(const char code[], bool experimental = false, const char filename[] = "test.cpp") { void check(const char code[], bool experimental = false, const char filename[] = "test.cpp") {
@ -1080,31 +1083,35 @@ private:
" return;\n" " return;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
}
void returnNonBoolLambda() {
check("bool f(void) {\n" check("bool f(void) {\n"
"auto x = [](void) { return -1; };\n" " auto x = [](void) { return -1; };\n"
"return false;\n" " return false;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("bool f(void) {\n" check("bool f(void) {\n"
"auto x = [](void) { return -1; };\n" " auto x = [](void) { return -1; };\n"
"return 2;\n" " return 2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str());
check("bool f(void) {\n" check("bool f(void) {\n"
"auto x = [](void) -> int { return -1; };\n" " auto x = [](void) -> int { return -1; };\n"
"return false;\n" " return false;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("bool f(void) {\n" check("bool f(void) {\n"
"auto x = [](void) -> int { return -1; };\n" " auto x = [](void) -> int { return -1; };\n"
"return 2;\n" " return 2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str());
}
void returnNonBoolLogicalOp() {
check("bool f(int x) {\n" check("bool f(int x) {\n"
" return x & 0x4;\n" " return x & 0x4;\n"
"}"); "}");
@ -1120,6 +1127,42 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void returnNonBoolClass() {
check("class X {\n"
" public:\n"
" bool f() { return -1;}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str());
check("bool f() {\n"
" struct X {\n"
" public:\n"
" int f() { return -1;}\n"
" };\n"
" return false;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("bool f() {\n"
" class X {\n"
" public:\n"
" int f() { return -1;}\n"
" };\n"
" return false;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("bool f() {\n"
" class X {\n"
" public:\n"
" bool f() { return -1;}\n"
" };\n"
" return -1;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Non-boolean value returned from function returning bool\n"
"[test.cpp:4]: (style) Non-boolean value returned from function returning bool\n", errout.str());
}
}; };
REGISTER_TEST(TestBool) REGISTER_TEST(TestBool)