diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index b47b16ea2..65b928f5e 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -1887,6 +1887,18 @@ static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data) } } + else if (const auto *f = data.settings->library.getAllocFuncInfo(tok->astOperand1())) { + if (!f->initData) { + const std::string name = data.getNewSymbolName(); + auto size = std::make_shared(data.getNewSymbolName(), 1, ~0U); + auto val = std::make_shared(); + auto result = std::make_shared(name, size, val, false, false, false); + call(data.callbacks, tok, result, &data); + data.functionCall(); + return result; + } + } + auto val = getValueRangeFromValueType(tok->valueType(), data); call(data.callbacks, tok, val, &data); data.functionCall(); diff --git a/test/testbughuntingchecks.cpp b/test/testbughuntingchecks.cpp index 8055033b4..9b1f35c71 100644 --- a/test/testbughuntingchecks.cpp +++ b/test/testbughuntingchecks.cpp @@ -25,21 +25,24 @@ class TestBughuntingChecks : public TestFixture { public: TestBughuntingChecks() : TestFixture("TestBughuntingChecks") { + settings.platform(cppcheck::Platform::Unix64); } private: + Settings settings; + void run() OVERRIDE { #ifdef USE_Z3 + LOAD_LIB_2(settings.library, "std.cfg"); TEST_CASE(uninit); TEST_CASE(uninit_array); TEST_CASE(uninit_function_par); + TEST_CASE(uninit_malloc); TEST_CASE(ctu); #endif } void check(const char code[]) { - Settings settings; - settings.platform(cppcheck::Platform::Unix64); Tokenizer tokenizer(&settings, this); std::istringstream istr(code); tokenizer.tokenize(istr, "test.cpp"); @@ -89,6 +92,11 @@ private: ASSERT_EQUALS("", errout.str()); } + void uninit_malloc() { + check("void foo() { char *p = malloc(10); return *p; }"); + ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that '*p' is initialized\n", errout.str()); + } + void ctu() { check("void init(int &x) {\n" " x = 1;\n"