From fc97a5b11cc9c91d280660938805fa75002dd04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 15 Aug 2018 18:04:36 +0200 Subject: [PATCH] Uninitalized variables: Fixed false positive --- lib/checkuninitvar.cpp | 6 +++++- test/testuninitvar.cpp | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index c1cb34a44..69acbea3e 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1076,8 +1076,12 @@ int CheckUninitVar::isFunctionParUsage(const Token *vartok, bool pointer, Alloc return 1; while (argStart->previous() && argStart->previous()->isName()) argStart = argStart->previous(); - if (Token::Match(argStart, "const %type% & %name% [,)]")) + if (Token::Match(argStart, "const %type% & %name% [,)]")) { + // If it's a record it's ok to pass a partially uninitialized struct. + if (vartok->variable() && vartok->variable()->valueType() && vartok->variable()->valueType()->type == ValueType::Type::RECORD) + return -1; return 1; + } if ((pointer || address) && alloc == NO_ALLOC && Token::Match(argStart, "const struct| %type% * %name% [,)]")) return 1; if ((pointer || address) && Token::Match(argStart, "const %type% %name% [") && Token::Match(argStart->linkAt(3), "] [,)]")) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e7dfab55f..99299370e 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -3048,6 +3048,15 @@ private: "}\n", "test.c"); ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str()); + checkUninitVar("struct AB { int a; int b; };\n" + "void do_something(const struct AB &ab) { a = ab.a; }\n" + "void f(void) {\n" + " struct AB ab;\n" + " ab.a = 0;\n" + " do_something(ab);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + checkUninitVar("struct AB { int a; int b; };\n" "void f(void) {\n" " struct AB ab;\n"