diff --git a/src/checkother.cpp b/src/checkother.cpp index 768efcebb..da8f8ce82 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -874,11 +874,20 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "struct|union|class {") || Token::Match(tok, "struct|union|class %type% {")) { - while (tok && tok->str() != "}") + int indentlevel0 = indentlevel; + + while (tok->str() != "{") tok = tok->next(); - if (tok) - continue; - break; + + do + { + if (tok->str() == "{") + indentlevel++; + else if (tok->str() == "}") + indentlevel--; + tok = tok->next(); + } + while (tok && indentlevel > indentlevel0); } if (Token::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|=")) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 6edba1b9c..87946d389 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -68,6 +68,7 @@ private: // Don't give false positives for variables in structs/unions TEST_CASE(localvarStruct1); TEST_CASE(localvarStruct2); + TEST_CASE(localvarStruct3); TEST_CASE(localvarOp); // Usage with arithmetic operators TEST_CASE(localvarInvert); // Usage with inverted variable @@ -259,6 +260,19 @@ private: ASSERT_EQUALS(std::string(""), errout.str()); } + void localvarStruct3() + { + functionVariableUsage("void foo()\n" + "{\n" + " int a = 10;\n" + " union { struct { unsigned char x; }; unsigned char z; };\n" + " do {\n" + " func();\n" + " } while(a--);\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + } + void localvarOp()