Skip to content

Commit 9778fd2

Browse files
committed
Fix #14005 FP: returnDanglingLifetime while returning reference to struct field
1 parent f28aeae commit 9778fd2

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

lib/valueflow.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18-
18+
#include <iostream>
1919
/**
2020
* @brief This is the ValueFlow component in Cppcheck.
2121
*
@@ -3119,6 +3119,14 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co
31193119
else if (tok->isUnaryOp("&")) {
31203120
if (Token::simpleMatch(tok->astParent(), "*"))
31213121
continue;
3122+
if (Token::simpleMatch(tok->astOperand1(), "[")) {
3123+
const Token* const op1 = tok->astOperand1()->astOperand1();
3124+
const Token* tok2 = op1;
3125+
while (Token::simpleMatch(tok2, "."))
3126+
tok2 = tok2->astOperand2();
3127+
if (tok2 && tok2 != op1 && (!tok2->variable() || !tok2->variable()->isArray()))
3128+
continue;
3129+
}
31223130
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1(), settings)) {
31233131
if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
31243132
continue;

test/testautovariables.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class TestAutoVariables : public TestFixture {
7878
TEST_CASE(testautovar_return3);
7979
TEST_CASE(testautovar_return4);
8080
TEST_CASE(testautovar_return5);
81+
TEST_CASE(testautovar_return6);
8182
TEST_CASE(testautovar_extern);
8283
TEST_CASE(testautovar_reassigned);
8384
TEST_CASE(testinvaliddealloc);
@@ -624,6 +625,17 @@ class TestAutoVariables : public TestFixture {
624625
ASSERT_EQUALS("", errout_str());
625626
}
626627

628+
void testautovar_return6() { // #14005
629+
check("struct S;\n"
630+
"struct S { const struct S *s; };\n"
631+
"extern struct T factory();\n"
632+
"const struct S* f() {\n"
633+
" struct T t = factory();\n"
634+
" return &t.s[0];\n"
635+
"}\n");
636+
ASSERT_EQUALS("", errout_str());
637+
}
638+
627639
void testautovar_extern() {
628640
check("struct foo *f()\n"
629641
"{\n"

0 commit comments

Comments
 (0)