From 185b88c6e3f3e788727d64ad0821e817b30bb353 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Wed, 6 Nov 2013 17:53:09 +0100 Subject: [PATCH] Ticket #5073: Don't crash upon invalid do-while loop. --- lib/checkuninitvar.cpp | 9 +++++---- test/testuninitvar.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 6ce990249..7224badb6 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1365,10 +1365,11 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, // do-while => goto ")" if (!forwhile) { // Assert that the tokens are '} while (' - if (testrunner && !Token::simpleMatch(tok, "} while (")) - reportError(tok,Severity::debug,"","assertion failed '} while ('"); - else - assert(Token::simpleMatch(tok, "} while (")); + if (!Token::simpleMatch(tok, "} while (")) { + if(_settings->debugwarnings) + reportError(tok,Severity::debug,"","assertion failed '} while ('"); + break; + } // Goto ')' tok = tok->linkAt(2); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e761e02c0..b9c9f5341 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -64,6 +64,8 @@ private: TEST_CASE(uninitvar2_structmembers); // struct members TEST_CASE(uninitvar2_while); TEST_CASE(uninitvar2_4494); // #4494 + + TEST_CASE(syntax_error); // Ticket #5073 } void checkUninitVar(const char code[], const char filename[] = "test.cpp") { @@ -2022,12 +2024,13 @@ private: /** 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.. errout.str(""); // Tokenize.. Settings settings; + settings.debugwarnings = debugwarnings; Tokenizer tokenizer(&settings, this); std::istringstream istr(code); tokenizer.tokenize(istr, fname); @@ -2963,7 +2966,7 @@ private: checkUninitVar2("void f() {\n" // #4911 - bad simplification => don't crash " int 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" "[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()); } + + 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)