diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index cb276188b..df694c13d 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -473,6 +473,8 @@ void CheckBool::returnValueOfFunctionReturningBool(void) const Token* tok2 = findLambdaEndToken(tok); if (tok2) tok = tok2; + else if (tok->scope() && tok->scope()->isClassOrStruct()) + tok = tok->scope()->bodyEnd; else if (Token::simpleMatch(tok, "return") && tok->astOperand1() && (tok->astOperand1()->getValueGE(2, mSettings) || tok->astOperand1()->getValueLE(-1, mSettings)) && !(tok->astOperand1()->astOperand1() && Token::Match(tok->astOperand1(), "&|%or%"))) diff --git a/test/testbool.cpp b/test/testbool.cpp index f9bf6c91c..3c629136a 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -66,6 +66,9 @@ private: TEST_CASE(pointerArithBool1); 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") { @@ -1080,31 +1083,35 @@ private: " return;\n" "}"); ASSERT_EQUALS("", errout.str()); + } + void returnNonBoolLambda() { check("bool f(void) {\n" - "auto x = [](void) { return -1; };\n" - "return false;\n" + " auto x = [](void) { return -1; };\n" + " return false;\n" "}\n"); ASSERT_EQUALS("", errout.str()); check("bool f(void) {\n" - "auto x = [](void) { return -1; };\n" - "return 2;\n" + " auto x = [](void) { return -1; };\n" + " return 2;\n" "}\n"); ASSERT_EQUALS("[test.cpp:3]: (style) Non-boolean value returned from function returning bool\n", errout.str()); check("bool f(void) {\n" - "auto x = [](void) -> int { return -1; };\n" - "return false;\n" + " auto x = [](void) -> int { return -1; };\n" + " return false;\n" "}\n"); ASSERT_EQUALS("", errout.str()); check("bool f(void) {\n" - "auto x = [](void) -> int { return -1; };\n" - "return 2;\n" + " auto x = [](void) -> int { return -1; };\n" + " return 2;\n" "}\n"); 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" " return x & 0x4;\n" "}"); @@ -1120,6 +1127,42 @@ private: "}"); 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)