Fix FP 8891: Incorrect return scope when using uniform initialization
This fixes the FP in: ```cpp std::string f(const std::string& data) { if (data.empty()) return {}; data[0]; } ```
This commit is contained in:
parent
888490fe6c
commit
be6782d386
|
@ -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"))
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue