diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6d0a2d237..3454390d2 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1438,6 +1438,49 @@ private: } } + /** + * Pointer assignment: p = x; + * if p is a pointer and x is an array/pointer then bail out + * \param checks all available checks + * \param tok1 the "p" token + * \param tok2 the "x" token + */ + static void pointer_assignment(std::list &checks, const Token *tok1, const Token *tok2) + { + const unsigned int varid1(tok1->varId()); + if (varid1 == 0) + return; + + const unsigned int varid2(tok2->varId()); + if (varid2 == 0) + return; + + std::list::const_iterator it; + + // bail out if first variable is a pointer + for (it = checks.begin(); it != checks.end(); ++it) + { + CheckUninitVar *c = dynamic_cast(*it); + if (c && c->varId == varid1 && c->pointer) + { + bailOutVar(checks, varid1); + break; + } + } + + // bail out if second variable is a array/pointer + for (it = checks.begin(); it != checks.end(); ++it) + { + CheckUninitVar *c = dynamic_cast(*it); + if (c && c->varId == varid2 && (c->pointer || c->array)) + { + bailOutVar(checks, varid2); + break; + } + } + } + + /** * use - called from the use* functions below. * @param foundError this is set to true if an error is found @@ -1650,6 +1693,12 @@ private: !Token::simpleMatch(tok2->next(), "=")) use(foundError, checks, tok2); } + + // pointer aliasing? + if (Token::Match(tok.tokAt(2), "%var% ;")) + { + pointer_assignment(checks, &tok, tok.tokAt(2)); + } } if (Token::Match(tok.tokAt(-2), "[;{}] *")) diff --git a/test/testother.cpp b/test/testother.cpp index 03f589a30..f08fdc584 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1166,6 +1166,15 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + checkUninitVar("void a()\n" + "{\n" + " char x[10], y[10];\n" + " char *z = x;\n" + " memset(z, 0, sizeof(x));\n" + " memcpy(y, x, sizeof(x));\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + checkUninitVar("int a()\n" "{\n" " int ret;\n"