Fixed #3651 (Preprocessor: Wrong handling of #elif)

This commit is contained in:
Kamil Dudka 2012-09-15 09:34:41 +02:00 committed by Daniel Marjamäki
parent 329f672334
commit b4d78e3d05
2 changed files with 33 additions and 3 deletions

View File

@ -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<bool> 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<bool>::reference elseIsTrue = elseIsTrueStack[indentmatch];
if (line.compare(0,7,"#ifdef ") == 0) {
if (indent == indentmatch) {
const std::string tag = getdef(line,true);

View File

@ -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<std::string, std::string> cfg;
@ -3279,7 +3281,7 @@ private:
}
}
void def_handleIncludes_ifelse() {
void def_handleIncludes_ifelse1() {
const std::string filePath("test.c");
const std::list<std::string> includePaths;
std::map<std::string,std::string> 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<std::string> includePaths;
std::map<std::string,std::string> 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).