Merge pull request #198 from simartin/ticket_5073

Ticket #5073: Don't crash upon invalid do-while loop.
This commit is contained in:
Daniel Marjamäki 2013-11-10 03:09:16 -08:00
commit 0dd17f9fad
2 changed files with 32 additions and 6 deletions

View File

@ -1365,10 +1365,11 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
// do-while => goto ")" // do-while => goto ")"
if (!forwhile) { if (!forwhile) {
// Assert that the tokens are '} while (' // Assert that the tokens are '} while ('
if (testrunner && !Token::simpleMatch(tok, "} while (")) if (!Token::simpleMatch(tok, "} while (")) {
reportError(tok,Severity::debug,"","assertion failed '} while ('"); if(_settings->debugwarnings)
else reportError(tok,Severity::debug,"","assertion failed '} while ('");
assert(Token::simpleMatch(tok, "} while (")); break;
}
// Goto ')' // Goto ')'
tok = tok->linkAt(2); tok = tok->linkAt(2);

View File

@ -64,6 +64,8 @@ private:
TEST_CASE(uninitvar2_structmembers); // struct members TEST_CASE(uninitvar2_structmembers); // struct members
TEST_CASE(uninitvar2_while); TEST_CASE(uninitvar2_while);
TEST_CASE(uninitvar2_4494); // #4494 TEST_CASE(uninitvar2_4494); // #4494
TEST_CASE(syntax_error); // Ticket #5073
} }
void checkUninitVar(const char code[], const char filename[] = "test.cpp") { void checkUninitVar(const char code[], const char filename[] = "test.cpp") {
@ -2022,12 +2024,13 @@ private:
/** New checking that doesn't rely on ExecutionPath */ /** New checking that doesn't rely on ExecutionPath */
void checkUninitVar2(const char code[], const char fname[] = "test.cpp", bool verify=true) { void checkUninitVar2(const char code[], const char fname[] = "test.cpp", bool verify=true, bool debugwarnings=false) {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
// Tokenize.. // Tokenize..
Settings settings; Settings settings;
settings.debugwarnings = debugwarnings;
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, fname); tokenizer.tokenize(istr, fname);
@ -2963,7 +2966,7 @@ private:
checkUninitVar2("void f() {\n" // #4911 - bad simplification => don't crash checkUninitVar2("void f() {\n" // #4911 - bad simplification => don't crash
" int a;\n" " int a;\n"
" do { } a=do_something(); while (a);\n" " do { } a=do_something(); while (a);\n"
"}\n"); "}\n", "test.cpp", /*verify=*/true, /*debugwarnings=*/true);
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n" ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n"
"[test.cpp:3]: (debug) assertion failed '} while ('\n", errout.str()); "[test.cpp:3]: (debug) assertion failed '} while ('\n", errout.str());
@ -3150,6 +3153,28 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:20]: (error) Uninitialized variable: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:20]: (error) Uninitialized variable: p\n", errout.str());
} }
void syntax_error() { // Ticket #5073
// Nominal mode => No output
checkUninitVar2("struct flex_array {};\n"
"struct cgroup_taskset {};\n"
"void cgroup_attach_task() {\n"
" struct flex_array *group;\n"
" struct cgroup_taskset tset = { };\n"
" do { } while_each_thread(leader, tsk);\n"
"}", "test.cpp", /*verify=*/true, /*debugwarnings=*/false);
ASSERT_EQUALS("", errout.str());
// --debug-warnings mode => Debug warning
checkUninitVar2("struct flex_array {};\n"
"struct cgroup_taskset {};\n"
"void cgroup_attach_task() {\n"
" struct flex_array *group;\n"
" struct cgroup_taskset tset = { };\n"
" do { } while_each_thread(leader, tsk);\n"
"}", "test.cpp", /*verify=*/true, /*debugwarnings=*/true);
ASSERT_EQUALS("[test.cpp:6]: (debug) assertion failed '} while ('\n", errout.str());
}
}; };
REGISTER_TEST(TestUninitVar) REGISTER_TEST(TestUninitVar)