From b4d78e3d053da3d4aabcc1b736dd541883c42c9b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Sat, 15 Sep 2012 09:34:41 +0200 Subject: [PATCH] Fixed #3651 (Preprocessor: Wrong handling of #elif) --- lib/preprocessor.cpp | 7 ++++++- test/testpreprocessor.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index db023ea71..1b1870d30 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1832,7 +1832,7 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str // has there been a true #if condition at the current indentmatch level? // then no more #elif or #else can be true before the #endif is seen. - bool elseIsTrue = true; + std::vector elseIsTrueStack; unsigned int linenr = 0; @@ -1845,6 +1845,11 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str while (std::getline(istr,line)) { ++linenr; + // has there been a true #if condition at the current indentmatch level? + // then no more #elif or #else can be true before the #endif is seen. + elseIsTrueStack.resize(1U + indentmatch, true); + std::vector::reference elseIsTrue = elseIsTrueStack[indentmatch]; + if (line.compare(0,7,"#ifdef ") == 0) { if (indent == indentmatch) { const std::string tag = getdef(line,true); diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 7be607525..f3b2e42e9 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -256,7 +256,8 @@ private: // Defines are given: test Preprocessor::handleIncludes TEST_CASE(def_handleIncludes); TEST_CASE(def_missingInclude); - TEST_CASE(def_handleIncludes_ifelse); // problems in handleIncludes for #else + TEST_CASE(def_handleIncludes_ifelse1); // problems in handleIncludes for #else + TEST_CASE(def_handleIncludes_ifelse2); TEST_CASE(def_valueWithParenthesis); // #3531 @@ -3078,6 +3079,7 @@ private: ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp")); } + void simplifyCondition() { // Ticket #2794 std::map cfg; @@ -3279,7 +3281,7 @@ private: } } - void def_handleIncludes_ifelse() { + void def_handleIncludes_ifelse1() { const std::string filePath("test.c"); const std::list includePaths; std::map defs; @@ -3334,6 +3336,29 @@ private: } } + void def_handleIncludes_ifelse2() { // #3651 + const char code[] = "#if defined(A)\n" + "\n" + "#if defined(B)\n" + "#endif\n" + "\n" + "#elif defined(C)\n" + "\n" + "#else\n" + "\n" + "123\n" + "\n" + "#endif"; + + Preprocessor preprocessor(NULL, this); + + const std::list includePaths; + std::map defs; + defs["A"] = "1"; + ASSERT_EQUALS(std::string::npos, // No "123" in the output + preprocessor.handleIncludes(code, "test.c", includePaths, defs).find("123")); + } + void def_valueWithParenthesis() { // #define should introduce a new symbol regardless of parenthesis in the value // and regardless of white space in weird places (people do this for some reason).