Fixed #2578 (Preprocessor does not correctly handle #define A 0 / #if A)

This commit is contained in:
Daniel Marjamäki 2011-02-23 13:08:24 -08:00
parent daf0e7c37d
commit 32a49235e3
2 changed files with 25 additions and 45 deletions

View File

@ -1289,8 +1289,12 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
if (Token::Match(tokenizer.tokens(), "( %var% )")) if (Token::Match(tokenizer.tokens(), "( %var% )"))
{ {
if (variables.find(tokenizer.tokens()->strAt(1)) != variables.end()) std::map<std::string,std::string>::const_iterator var = variables.find(tokenizer.tokens()->strAt(1));
condition = "1"; if (var != variables.end())
{
const std::string &value = (*var).second;
condition = (value == "0") ? "0" : "1";
}
else if (match) else if (match)
condition = "0"; condition = "0";
return; return;

View File

@ -114,7 +114,6 @@ private:
TEST_CASE(if_cond4); TEST_CASE(if_cond4);
TEST_CASE(if_cond5); TEST_CASE(if_cond5);
TEST_CASE(if_cond6); TEST_CASE(if_cond6);
TEST_CASE(if_cond7);
TEST_CASE(if_cond8); TEST_CASE(if_cond8);
TEST_CASE(if_cond9); TEST_CASE(if_cond9);
TEST_CASE(if_cond10); TEST_CASE(if_cond10);
@ -195,6 +194,7 @@ private:
TEST_CASE(ifdef_ifdefined); TEST_CASE(ifdef_ifdefined);
// define and then ifdef // define and then ifdef
TEST_CASE(define_if);
TEST_CASE(define_ifdef); TEST_CASE(define_ifdef);
TEST_CASE(define_ifndef1); TEST_CASE(define_ifndef1);
TEST_CASE(define_ifndef2); TEST_CASE(define_ifndef2);
@ -1234,48 +1234,6 @@ private:
ASSERT_EQUALS("[file.c:2]: (error) mismatching number of '(' and ')' in this line: defined(A)&&defined(B))\n", errout.str()); ASSERT_EQUALS("[file.c:2]: (error) mismatching number of '(' and ')' in this line: defined(A)&&defined(B))\n", errout.str());
} }
void if_cond7()
{
{
const char filedata[] = "#define A 1\n"
"#if A==1\n"
"a1;\n"
"#endif\n";
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Settings settings;
Preprocessor preprocessor(&settings, this);
preprocessor.preprocess(istr, actual, "file.c");
// Compare results..
ASSERT_EQUALS(1, (int)actual.size());
ASSERT_EQUALS("\n\na1;\n\n", actual[""]);
}
{
const char filedata[] = "#define A 0\n"
"#if A\n"
"foo();\n"
"#endif\n";
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Settings settings;
Preprocessor preprocessor(&settings, this);
preprocessor.preprocess(istr, actual, "file.c");
// Compare results..
TODO_ASSERT_EQUALS(2,
1, static_cast<unsigned int>(actual.size()));
TODO_ASSERT_EQUALS("\n\n\n\n",
"\n\nfoo();\n\n", actual[""]);
}
}
void if_cond8() void if_cond8()
{ {
const char filedata[] = "#if defined(A) + defined(B) + defined(C) != 1\n" const char filedata[] = "#if defined(A) + defined(B) + defined(C) != 1\n"
@ -2442,6 +2400,24 @@ private:
ASSERT_EQUALS(2, static_cast<unsigned int>(actual.size())); ASSERT_EQUALS(2, static_cast<unsigned int>(actual.size()));
} }
void define_if()
{
{
const char filedata[] = "#define A 0\n"
"#if A\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\n\n\n", Preprocessor::getcode(filedata,"","",NULL,NULL));
}
{
const char filedata[] = "#define A 1\n"
"#if A==1\n"
"FOO\n"
"#endif";
ASSERT_EQUALS("\n\nFOO\n\n", Preprocessor::getcode(filedata,"","",NULL,NULL));
}
}
void define_ifdef() void define_ifdef()
{ {
{ {