From 37d9d6fd7e60846ac81b37e65e45e0521064ddeb Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 10 Jul 2012 05:47:51 -0700 Subject: [PATCH] Improved parsing of C++11 initializer list (#3956) in CheckClass::initializeVarList. --- lib/checkclass.cpp | 24 ++++++++++++++---------- test/testconstructors.cpp | 12 ++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 03bf34fc4..1ffae490c 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -236,7 +236,8 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope) void CheckClass::initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage) { bool initList = true; - const Token *ftok = func.arg->link(); + const Token *ftok = func.arg->link()->next(); + int level = 0; for (; ftok != func.functionScope->classEnd; ftok = ftok->next()) { if (!ftok->next()) @@ -245,20 +246,23 @@ void CheckClass::initializeVarList(const Function &func, std::list // Class constructor.. initializing variables like this // clKalle::clKalle() : var(value) { } if (initList) { - if (Token::Match(ftok, "%var% (")) { + if (level == 0 && Token::Match(ftok, "%var% (")) initVar(ftok->str(), scope, usage); + else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x) + assignVar(ftok->str(), scope, usage); - // assignment in the initializer.. - // : var(value = x) - if (Token::Match(ftok->tokAt(2), "%var% =")) - assignVar(ftok->strAt(2), scope, usage); + else if (ftok->str() == "(") + level++; + else if (ftok->str() == ")") + level--; + else if (ftok->str() == "{") { + if (level == 0) + initList = false; + else + ftok = ftok->link(); } } - - if (ftok->str() == "{") - initList = false; - if (initList) continue; diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 769ecea54..27e5cf399 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -118,6 +118,7 @@ private: TEST_CASE(uninitVarArray8); TEST_CASE(uninitVarArray2D); TEST_CASE(uninitVarArray3D); + TEST_CASE(uninitVarCpp11Init); TEST_CASE(uninitVarStruct1); // ticket #2172 TEST_CASE(uninitVarStruct2); // ticket #838 TEST_CASE(uninitVarUnion1); // ticket #3196 @@ -1694,6 +1695,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void uninitVarCpp11Init() { + check("class Foo {\n" + " std::vector bar;\n" + "public:\n" + " Foo()\n" + " : bar({\"a\", \"b\"})\n" + " {}\n" + "};"); + ASSERT_EQUALS("", errout.str()); + } + void uninitVarStruct1() { // ticket #2172 check("class A\n" "{\n"