diff --git a/lib/astutils.cpp b/lib/astutils.cpp index b1542902b..fd820d0cd 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -772,16 +772,19 @@ bool isReturnScope(const Token * const endToken) !Token::findsimplematch(prev->link(), "break", prev)) { return true; } - if (Token::simpleMatch(prev->link()->previous(), ") {") && - Token::simpleMatch(prev->link()->linkAt(-1)->previous(), "return (")) { + if (Token::Match(prev->link()->astTop(), "return|throw")) return true; - } if (Token::Match(prev->link()->previous(), "[;{}] {")) return isReturnScope(prev); } else if (Token::simpleMatch(prev, ";")) { // noreturn function if (Token::simpleMatch(prev->previous(), ") ;") && Token::Match(prev->linkAt(-1)->tokAt(-2), "[;{}] %name% (")) return true; + if (Token::simpleMatch(prev->previous(), ") ;") && prev->previous()->link() && + Token::Match(prev->previous()->link()->astTop(), "return|throw")) + return true; + if (Token::Match(prev->previous()->astTop(), "return|throw")) + return true; // return/goto statement prev = prev->previous(); while (prev && !Token::Match(prev, ";|{|}|return|goto|throw|continue|break")) diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 1315382da..79fef5980 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -85,10 +85,17 @@ private: void isReturnScope() { ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return; } }", -2)); + ASSERT_EQUALS(true, isReturnScope("int f() { if (a) { return {}; } }", -2)); // #8891 + ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{}; } }", -2)); // #8891 + ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{\"\"}; } }", -2)); // #8891 ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return (ab){0}; } }", -2)); // #7103 ASSERT_EQUALS(false, isReturnScope("void f() { if (a) { return (ab){0}; } }", -4)); // #7103 ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }", -4)); // #7144 ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }", -2)); // #7144 + ASSERT_EQUALS(false, isReturnScope("void f() { [=]() { return data; }; }", -1)); + ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }; }", -1)); + ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }(); }", -1)); + ASSERT_EQUALS(false, isReturnScope("auto f() { [=]() { return data; }(); }", -1)); } bool isVariableChanged(const char code[], const char startPattern[], const char endPattern[]) { diff --git a/test/teststl.cpp b/test/teststl.cpp index 37e5f1b03..135b54f16 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -263,6 +263,18 @@ private: " c.data();\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + checkNormal("std::string f(std::string x) {\n" + " if (x.empty()) return {};\n" + " x[0];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + checkNormal("std::string f(std::string x) {\n" + " if (x.empty()) return std::string{};\n" + " x[0];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void outOfBoundsIndexExpression() {