diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 0e73d66d0..58f43decb 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -33,6 +33,17 @@ CheckUninitVar instance; //--------------------------------------------------------------------------- +/** Is string uppercase? */ +static bool isUpper(const std::string &str) +{ + for (unsigned int i = 0; i < str.length(); ++i) + { + if (str[i] >= 'a' && str[i] <= 'z') + return false; + } + return true; +} + /// @addtogroup Checks /// @{ @@ -578,7 +589,9 @@ private: if (Token::Match(&tok, "%var% (") && uvarFunctions.find(tok.str()) == uvarFunctions.end()) { - if (Token::Match(&tok, "sizeof|typeof (")) + // sizeof/typeof doesn't dereference. A function name that is all uppercase + // might be an unexpanded macro that uses sizeof/typeof + if (Token::Match(&tok, "sizeof|typeof (") || isUpper(tok.str())) return tok.next()->link(); // deallocate pointer @@ -656,6 +669,14 @@ private: break; } + // ticket #2367 : unexpanded macro that uses sizeof|typeof? + else if (Token::Match(tok2, "%type% (") && isUpper(tok2->str())) + { + tok2 = tok2->next()->link(); + if (!tok2) + break; + } + else if (tok2->varId()) { if (Token::Match(tok2->tokAt(-2), "[(,] *") || Token::Match(tok2->next(), ". %var%")) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index b69a977cd..a72284870 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1406,6 +1406,12 @@ private: " ab(typeof(s->status));\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + checkUninitVar("void f() {\n" + " struct SData * s;\n" + " TYPEOF(s->status);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } };