diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index cc3f761a6..2cc9125b2 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1327,6 +1327,13 @@ bool CheckUninitVar::isUnsafeFunction(const Scope *scope, int argnr, const Token if (!argvar->isPointer()) return false; for (const Token *tok2 = scope->classStart; tok2 != scope->classEnd; tok2 = tok2->next()) { + if (Token::simpleMatch(tok2, ") {")) { + tok2 = tok2->linkAt(1); + if (Token::findmatch(tok2->link(), "return|throw", tok2)) + return false; + if (isVariableChanged(tok2->link(), tok2, argvar->declarationId(), false, _settings)) + return false; + } if (tok2->variable() != argvar) continue; if (!isVariableUsage(tok2, true, Alloc::ARRAY)) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index af165f704..d44e0deaa 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -4011,6 +4011,31 @@ private: " call(4,&x);\n" "}"); ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (error) using argument p that points at uninitialized variable x\n", errout.str()); + + ctu("void dostuff(int *x, int *y) {\n" + " if (!var)\n" + " return -1;\n" // <- early return + " *x = *y;\n" + "}\n" + "\n" + "void f() {\n" + " int x;\n" + " dostuff(a, &x);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + ctu("void dostuff(int *x, int *y) {\n" + " if (cond)\n" + " *y = -1;\n" // <- conditionally written + " *x = *y;\n" + "}\n" + "\n" + "void f() {\n" + " int x;\n" + " dostuff(a, &x);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } };