From e1513090e269bbf9073ad1438acfc729bc5a3759 Mon Sep 17 00:00:00 2001 From: Alexander Mai Date: Sun, 8 Jun 2014 10:02:16 +0200 Subject: [PATCH] #5909 crash: clang: test/Preprocessor/ifdef-recover.c. Avoid segfault in Preprocessor::getcfgs() on invalid code. --- lib/preprocessor.cpp | 4 ++-- test/testpreprocessor.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index a9052ad15..1cfdd0b09 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1432,7 +1432,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } else if (line.compare(0, 5, "#else") == 0 && ! deflist.empty()) { - if (deflist.back() == "!") { + if (deflist.back() == "!" && !ndeflist.empty()) { deflist.back() = ndeflist.back(); ndeflist.pop_back(); } else { @@ -1442,7 +1442,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } else if (line.compare(0, 6, "#endif") == 0 && ! deflist.empty()) { - if (deflist.back() == "!") + if (deflist.back() == "!" && !ndeflist.empty()) ndeflist.pop_back(); deflist.pop_back(); } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index e0f32b3d8..d98e7f90b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -302,6 +302,7 @@ private: TEST_CASE(if_sizeof); TEST_CASE(double_include); // #5717 + TEST_CASE(invalid_ifs)// #5909 } @@ -4042,6 +4043,27 @@ private: std::set pragmaOnce; preprocessor.handleIncludes(code, "123.h", includePaths, defs, pragmaOnce, std::list()); } + + void invalid_ifs() { + const char filedata[] = "#ifdef\n" + "#endif\n" + "#ifdef !\n" + "#endif\n" + "#if defined\n" + "#endif\n" + "#define f(x) x\n" + "#if f(2\n" + "#endif\n" + "int x;\n"; + + // Preprocess => don't crash.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + preprocessor.preprocess(istr, actual, "file.c"); + + } }; REGISTER_TEST(TestPreprocessor)