Fix 10532: False negative: dangling string_view when using ternary operator (#4638)
* Fix 10532: False negative: dangling string_view when using ternary operator * Format * Update
This commit is contained in:
parent
553b579f8d
commit
90898945c1
|
@ -397,12 +397,18 @@ bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknow
|
|||
return isTemporary(cpp, tok->astOperand2(), library);
|
||||
if (tok->isCast() || (cpp && isCPPCast(tok)))
|
||||
return isTemporary(cpp, tok->astOperand2(), library);
|
||||
if (Token::Match(tok, "?|.|[|++|--|%name%|%assign%"))
|
||||
if (Token::Match(tok, ".|[|++|--|%name%|%assign%"))
|
||||
return false;
|
||||
if (tok->isUnaryOp("*"))
|
||||
return false;
|
||||
if (Token::Match(tok, "&|<<|>>") && isLikelyStream(cpp, tok->astOperand1()))
|
||||
return false;
|
||||
if (Token::simpleMatch(tok, "?")) {
|
||||
const Token* branchTok = tok->astOperand2();
|
||||
if (!branchTok->astOperand1()->valueType())
|
||||
return false;
|
||||
return !branchTok->astOperand1()->valueType()->isTypeEqual(branchTok->astOperand2()->valueType());
|
||||
}
|
||||
if (Token::simpleMatch(tok, "(") && tok->astOperand1() &&
|
||||
(tok->astOperand2() || Token::simpleMatch(tok->next(), ")"))) {
|
||||
if (tok->valueType()) {
|
||||
|
|
|
@ -6386,14 +6386,26 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
|
|||
return;
|
||||
}
|
||||
|
||||
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
|
||||
setValueType(parent, *vt1);
|
||||
return;
|
||||
}
|
||||
if (parent->isArithmeticalOp()) {
|
||||
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
|
||||
setValueType(parent, *vt1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
|
||||
setValueType(parent, *vt2);
|
||||
return;
|
||||
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
|
||||
setValueType(parent, *vt2);
|
||||
return;
|
||||
}
|
||||
} else if (ternary) {
|
||||
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
|
||||
setValueType(parent, *vt2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
|
||||
setValueType(parent, *vt1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (vt1->pointer != 0U) {
|
||||
|
@ -7309,6 +7321,8 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform, bool p)
|
|||
|
||||
bool ValueType::isTypeEqual(const ValueType* that) const
|
||||
{
|
||||
if (!that)
|
||||
return false;
|
||||
auto tie = [](const ValueType* vt) {
|
||||
return std::tie(vt->type, vt->container, vt->pointer, vt->typeScope, vt->smartPointer);
|
||||
};
|
||||
|
|
|
@ -2757,6 +2757,15 @@ private:
|
|||
" return v[0];\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #10532
|
||||
check("std::string f(std::string ss) {\n"
|
||||
" std::string_view sv = true ? \"\" : ss;\n"
|
||||
" std::string s = sv;\n"
|
||||
" return s;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2] -> [test.cpp:3]: (error) Using object that is a temporary.\n",
|
||||
errout.str());
|
||||
}
|
||||
|
||||
void danglingLifetimeUniquePtr()
|
||||
|
|
Loading…
Reference in New Issue