Skip to content

Commit 9089894

Browse files
authored
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
1 parent 553b579 commit 9089894

3 files changed

Lines changed: 37 additions & 8 deletions

File tree

lib/astutils.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,12 +397,18 @@ bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknow
397397
return isTemporary(cpp, tok->astOperand2(), library);
398398
if (tok->isCast() || (cpp && isCPPCast(tok)))
399399
return isTemporary(cpp, tok->astOperand2(), library);
400-
if (Token::Match(tok, "?|.|[|++|--|%name%|%assign%"))
400+
if (Token::Match(tok, ".|[|++|--|%name%|%assign%"))
401401
return false;
402402
if (tok->isUnaryOp("*"))
403403
return false;
404404
if (Token::Match(tok, "&|<<|>>") && isLikelyStream(cpp, tok->astOperand1()))
405405
return false;
406+
if (Token::simpleMatch(tok, "?")) {
407+
const Token* branchTok = tok->astOperand2();
408+
if (!branchTok->astOperand1()->valueType())
409+
return false;
410+
return !branchTok->astOperand1()->valueType()->isTypeEqual(branchTok->astOperand2()->valueType());
411+
}
406412
if (Token::simpleMatch(tok, "(") && tok->astOperand1() &&
407413
(tok->astOperand2() || Token::simpleMatch(tok->next(), ")"))) {
408414
if (tok->valueType()) {

lib/symboldatabase.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6386,14 +6386,26 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
63866386
return;
63876387
}
63886388

6389-
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
6390-
setValueType(parent, *vt1);
6391-
return;
6392-
}
6389+
if (parent->isArithmeticalOp()) {
6390+
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
6391+
setValueType(parent, *vt1);
6392+
return;
6393+
}
63936394

6394-
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
6395-
setValueType(parent, *vt2);
6396-
return;
6395+
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
6396+
setValueType(parent, *vt2);
6397+
return;
6398+
}
6399+
} else if (ternary) {
6400+
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
6401+
setValueType(parent, *vt2);
6402+
return;
6403+
}
6404+
6405+
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
6406+
setValueType(parent, *vt1);
6407+
return;
6408+
}
63976409
}
63986410

63996411
if (vt1->pointer != 0U) {
@@ -7309,6 +7321,8 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform, bool p)
73097321

73107322
bool ValueType::isTypeEqual(const ValueType* that) const
73117323
{
7324+
if (!that)
7325+
return false;
73127326
auto tie = [](const ValueType* vt) {
73137327
return std::tie(vt->type, vt->container, vt->pointer, vt->typeScope, vt->smartPointer);
73147328
};

test/testautovariables.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,15 @@ class TestAutoVariables : public TestFixture {
27572757
" return v[0];\n"
27582758
"}\n");
27592759
ASSERT_EQUALS("", errout.str());
2760+
2761+
// #10532
2762+
check("std::string f(std::string ss) {\n"
2763+
" std::string_view sv = true ? \"\" : ss;\n"
2764+
" std::string s = sv;\n"
2765+
" return s;\n"
2766+
"}\n");
2767+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2] -> [test.cpp:3]: (error) Using object that is a temporary.\n",
2768+
errout.str());
27602769
}
27612770

27622771
void danglingLifetimeUniquePtr()

0 commit comments

Comments
 (0)