Fix ticket #315 (Segmentation fault when checking Linux kernel)
http://apps.sourceforge.net/trac/cppcheck/ticket/315
This commit is contained in:
parent
927918f9b0
commit
d6d55c2db4
|
@ -713,10 +713,8 @@ public:
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string code(const std::vector<std::string> ¶ms2) const
|
bool code(const std::vector<std::string> ¶ms2, std::string ¯ocode) const
|
||||||
{
|
{
|
||||||
std::string macrocode;
|
|
||||||
|
|
||||||
if (_params.empty())
|
if (_params.empty())
|
||||||
{
|
{
|
||||||
std::string::size_type pos = _macro.find(" ");
|
std::string::size_type pos = _macro.find(" ");
|
||||||
|
@ -765,12 +763,18 @@ public:
|
||||||
optcomma = false;
|
optcomma = false;
|
||||||
str += params2[j];
|
str += params2[j];
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (stringify)
|
else if (i >= params2.size())
|
||||||
|
{
|
||||||
|
// Macro had more parameters than caller used.
|
||||||
|
macrocode = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (stringify)
|
||||||
str = "\"" + params2[i] + "\"";
|
str = "\"" + params2[i] + "\"";
|
||||||
else
|
else
|
||||||
str = params2[i];
|
str = params2[i];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,7 +792,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return macrocode;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -879,6 +883,7 @@ std::string Preprocessor::expandMacros(std::string code, const std::string &file
|
||||||
|
|
||||||
if (errorLogger)
|
if (errorLogger)
|
||||||
{
|
{
|
||||||
|
// TODO, duplicate code. Refactor
|
||||||
std::string fname(filename);
|
std::string fname(filename);
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
for (std::string::size_type p = pos1; p > 0; --p)
|
for (std::string::size_type p = pos1; p > 0; --p)
|
||||||
|
@ -1022,7 +1027,58 @@ std::string Preprocessor::expandMacros(std::string code, const std::string &file
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Create macro code..
|
// Create macro code..
|
||||||
const std::string macrocode(std::string(numberOfNewlines, '\n') + macro.code(params));
|
std::string tempMacro;
|
||||||
|
if (!macro.code(params, tempMacro))
|
||||||
|
{
|
||||||
|
// Syntax error in code
|
||||||
|
if (errorLogger)
|
||||||
|
{
|
||||||
|
std::string fname(filename);
|
||||||
|
int lineno = 1;
|
||||||
|
for (std::string::size_type p = pos1; p > 0; --p)
|
||||||
|
{
|
||||||
|
// newline..
|
||||||
|
if (code[p-1] == '\n')
|
||||||
|
lineno++;
|
||||||
|
|
||||||
|
// #file..
|
||||||
|
else if (code[p-1] == '#')
|
||||||
|
{
|
||||||
|
// Previous char should be a newline..
|
||||||
|
if (p == 1 || code[p-2] == '\n')
|
||||||
|
{
|
||||||
|
// #file..
|
||||||
|
if (code.substr(p - 1, 6) == "#file ")
|
||||||
|
{
|
||||||
|
fname = code.substr(p + 5, code.find("\n", p) - p - 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
++lineno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start of file..
|
||||||
|
else if (p == 1)
|
||||||
|
++lineno;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||||
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
loc.line = lineno;
|
||||||
|
loc.file = fname;
|
||||||
|
locationList.push_back(loc);
|
||||||
|
errorLogger->reportErr(
|
||||||
|
ErrorLogger::ErrorMessage(locationList,
|
||||||
|
"error",
|
||||||
|
std::string("Syntax error. Not enough parameters for macro '") + macro.name() + "'.",
|
||||||
|
"syntaxError"));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string macrocode(std::string(numberOfNewlines, '\n') + tempMacro);
|
||||||
|
|
||||||
// Insert macro code..
|
// Insert macro code..
|
||||||
if (!macro.params().empty())
|
if (!macro.params().empty())
|
||||||
|
|
|
@ -124,6 +124,7 @@ private:
|
||||||
TEST_CASE(define_part_of_func);
|
TEST_CASE(define_part_of_func);
|
||||||
TEST_CASE(conditionalDefine);
|
TEST_CASE(conditionalDefine);
|
||||||
TEST_CASE(multiline_comment);
|
TEST_CASE(multiline_comment);
|
||||||
|
TEST_CASE(macro_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1008,6 +1009,28 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void macro_parameters()
|
||||||
|
{
|
||||||
|
errout.str("");
|
||||||
|
const char filedata[] = "#define BC(a, b, c, arg...) \\\n"
|
||||||
|
"AB(a, b, c, ## arg)\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" BC(3);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
// Preprocess => actual result..
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
std::map<std::string, std::string> actual;
|
||||||
|
Preprocessor preprocessor;
|
||||||
|
preprocessor.preprocess(istr, actual, "file.c", std::list<std::string>(), this);
|
||||||
|
|
||||||
|
// Compare results..
|
||||||
|
ASSERT_EQUALS(1, static_cast<unsigned int>(actual.size()));
|
||||||
|
ASSERT_EQUALS("", actual[""]);
|
||||||
|
ASSERT_EQUALS("[file.c:6]: (error) Syntax error. Not enough parameters for macro 'BC'.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue