From 76989b11932f946a41cd60fa7e8f8acde1150ab0 Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 14 Jul 2023 16:44:33 +0200 Subject: [PATCH 1/2] Fix #11832 False positive: uninitialized variable '*(&var) = 0' --- lib/checkuninitvar.cpp | 2 +- lib/checkunusedvar.cpp | 2 +- test/testuninitvar.cpp | 10 ++++++++++ test/testunusedvar.cpp | 6 ++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index aca9c6e87ce..e30dfebc14b 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1248,7 +1248,7 @@ const Token* CheckUninitVar::isVariableUsage(bool cpp, const Token *vartok, cons } if (Token::simpleMatch(tok->astParent(), "=")) { if (astIsLhs(tok)) { - if (alloc == ARRAY || !derefValue || !derefValue->isUnaryOp("*")) + if (alloc == ARRAY || !derefValue || !derefValue->isUnaryOp("*") || !pointer) return nullptr; const Token* deref = derefValue->astOperand1(); while (deref && deref->isCast()) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 7946f337f71..dfe2d83ee6b 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1009,7 +1009,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const // assignment else if ((Token::Match(tok, "%name% [") && Token::simpleMatch(skipBracketsAndMembers(tok->next()), "=")) || - (Token::simpleMatch(tok, "* (") && Token::simpleMatch(tok->next()->link(), ") ="))) { + (tok->isUnaryOp("*") && tok->astParent() && tok->astParent()->isAssignmentOp() && Token::simpleMatch(tok->astOperand1(), "+"))) { const Token *eq = tok; while (eq && !eq->isAssignmentOp()) eq = eq->astParent(); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 520336e3899..6096a456897 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -75,6 +75,7 @@ class TestUninitVar : public TestFixture { TEST_CASE(uninitvar11); // ticket #9123 TEST_CASE(uninitvar12); // #10218 - stream read TEST_CASE(uninitvar13); // #9772 + TEST_CASE(uninitvar14); TEST_CASE(uninitvar_unconditionalTry); TEST_CASE(uninitvar_funcptr); // #6404 TEST_CASE(uninitvar_operator); // #6680 @@ -3126,6 +3127,15 @@ class TestUninitVar : public TestFixture { ASSERT_EQUALS("", errout.str()); } + void uninitvar14() { // #11832 + const char code[] = "void f() {\n" + " int b;\n" + " *(&b) = 0;\n" + "}"; + checkUninitVar(code); + ASSERT_EQUALS("", errout.str()); + } + void uninitvar_unconditionalTry() { // Unconditional scopes and try{} scopes checkUninitVar("int f() {\n" diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 49c024c3af1..181445bd0be 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -2640,6 +2640,12 @@ class TestUnusedVar : public TestFixture { " *(b+i) = 0;\n" "}"); TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable '*(b+i)' is assigned a value that is never used.\n", "", errout.str()); + + functionVariableUsage("void f() {\n" // #11832 + " int b;\n" + " *(&b) = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void localvar8() { From 6502950aed36e31aa2bdf65dff0a3451f6717168 Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 14 Jul 2023 16:52:36 +0200 Subject: [PATCH 2/2] simpleMatch --- lib/checkunusedvar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index dfe2d83ee6b..bd42a61824c 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1009,7 +1009,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const // assignment else if ((Token::Match(tok, "%name% [") && Token::simpleMatch(skipBracketsAndMembers(tok->next()), "=")) || - (tok->isUnaryOp("*") && tok->astParent() && tok->astParent()->isAssignmentOp() && Token::simpleMatch(tok->astOperand1(), "+"))) { + (tok->isUnaryOp("*") && Token::simpleMatch(tok->astParent(), "=") && Token::simpleMatch(tok->astOperand1(), "+"))) { const Token *eq = tok; while (eq && !eq->isAssignmentOp()) eq = eq->astParent();