Test for return address of reference (#2991)
This commit is contained in:
parent
28b4d1a6b3
commit
53734a3da1
|
@ -2742,7 +2742,8 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
|
|||
} else if (Token::simpleMatch(var->declEndToken(), "=")) {
|
||||
errorPath.emplace_back(var->declEndToken(), "Assigned to reference.");
|
||||
const Token *vartok = var->declEndToken()->astOperand2();
|
||||
const bool temporary = isTemporary(true, vartok, nullptr, true);
|
||||
const bool temporaryDefault = false; //If we can't tell then assume the value is not temporary as this will result in fewer false positives.
|
||||
const bool temporary = isTemporary(true, vartok, nullptr, temporaryDefault);
|
||||
const bool nonlocal = var->isStatic() || var->isGlobal();
|
||||
if (vartok == tok || (nonlocal && temporary) || (!escape && (var->isConst() || var->isRValueReference()) && temporary))
|
||||
return {{tok, true, std::move(errorPath)}};
|
||||
|
|
|
@ -2564,6 +2564,21 @@ private:
|
|||
" }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
//Make sure we can still take the address of a reference without warning
|
||||
check("int* foo() {\n"
|
||||
" int& x = getX();\n"
|
||||
" return &x;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
check("struct C {\n"
|
||||
" int* m_x;\n"
|
||||
" void foo() {\n"
|
||||
" const int& x = getX();\n"
|
||||
" m_x = &x;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void danglingLifetimeFunction() {
|
||||
|
|
Loading…
Reference in New Issue