diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2c01884c9ef..83583a6186c 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -398,12 +398,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()) { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 82151ff483c..bd18cf24e13 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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); }; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 781141bc417..2efdb20d07a 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2757,6 +2757,15 @@ class TestAutoVariables : public TestFixture { " 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()