"Internal error. Token::Match called with varid 0." didn't work when error was in a header file. Fixed that.

This commit is contained in:
Reijo Tomperi 2011-11-21 00:41:26 +02:00
parent 7d7d68b192
commit eebd1393ff
3 changed files with 120 additions and 113 deletions

View File

@ -115,11 +115,7 @@ bool CppCheck::findError(std::string code, const char FileName[])
// is still there. // is still there.
code = previousCode.substr(found+9); code = previousCode.substr(found+9);
_errorList.clear(); _errorList.clear();
try { checkFile(code, FileName);
checkFile(code, FileName);
} catch (ErrorLogger::ErrorMessage &err) {
reportErr(err);
}
} }
if (_errorList.empty()) { if (_errorList.empty()) {
@ -254,18 +250,6 @@ unsigned int CppCheck::processFile()
// Exception was thrown when checking this file.. // Exception was thrown when checking this file..
const std::string fixedpath = Path::toNativeSeparators(_filename); const std::string fixedpath = Path::toNativeSeparators(_filename);
_errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what()); _errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
} catch (ErrorLogger::ErrorMessage &err) {
// Catch exception from Token class
const std::string fixedpath = Path::toNativeSeparators(_filename);
if (err._callStack.empty()) {
ErrorLogger::ErrorMessage::FileLocation loc;
loc.setfile(fixedpath);
err._callStack.push_back(loc);
} else {
err._callStack.begin()->setfile(fixedpath);
}
_errorLogger.reportErr(err);
} }
if (!_settings._errorsOnly) if (!_settings._errorsOnly)
@ -337,123 +321,146 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
return; return;
Tokenizer _tokenizer(&_settings, this); Tokenizer _tokenizer(&_settings, this);
bool result; try {
bool result;
// Tokenize the file // Tokenize the file
std::istringstream istr(code); std::istringstream istr(code);
Timer timer("Tokenizer::tokenize", _settings._showtime, &S_timerResults); Timer timer("Tokenizer::tokenize", _settings._showtime, &S_timerResults);
result = _tokenizer.tokenize(istr, FileName, cfg); result = _tokenizer.tokenize(istr, FileName, cfg);
timer.Stop(); timer.Stop();
if (!result) { if (!result) {
// File had syntax errors, abort // File had syntax errors, abort
return; return;
} }
Timer timer2("Tokenizer::fillFunctionList", _settings._showtime, &S_timerResults); Timer timer2("Tokenizer::fillFunctionList", _settings._showtime, &S_timerResults);
_tokenizer.fillFunctionList(); _tokenizer.fillFunctionList();
timer2.Stop(); timer2.Stop();
// call all "runChecks" in all registered Check classes // call all "runChecks" in all registered Check classes
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) { for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
if (_settings.terminated()) if (_settings.terminated())
return;
Timer timerRunChecks((*it)->name() + "::runChecks", _settings._showtime, &S_timerResults);
(*it)->runChecks(&_tokenizer, &_settings, this);
}
Timer timer3("Tokenizer::simplifyTokenList", _settings._showtime, &S_timerResults);
result = _tokenizer.simplifyTokenList();
timer3.Stop();
if (!result)
return; return;
Timer timerRunChecks((*it)->name() + "::runChecks", _settings._showtime, &S_timerResults); Timer timer4("Tokenizer::fillFunctionList", _settings._showtime, &S_timerResults);
(*it)->runChecks(&_tokenizer, &_settings, this); _tokenizer.fillFunctionList();
} timer4.Stop();
Timer timer3("Tokenizer::simplifyTokenList", _settings._showtime, &S_timerResults); if (_settings.isEnabled("unusedFunction") && _settings._jobs == 1)
result = _tokenizer.simplifyTokenList(); _checkUnusedFunctions.parseTokens(_tokenizer);
timer3.Stop();
if (!result)
return;
Timer timer4("Tokenizer::fillFunctionList", _settings._showtime, &S_timerResults); // call all "runSimplifiedChecks" in all registered Check classes
_tokenizer.fillFunctionList(); for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
timer4.Stop(); if (_settings.terminated())
return;
if (_settings.isEnabled("unusedFunction") && _settings._jobs == 1) Timer timerSimpleChecks((*it)->name() + "::runSimplifiedChecks", _settings._showtime, &S_timerResults);
_checkUnusedFunctions.parseTokens(_tokenizer); (*it)->runSimplifiedChecks(&_tokenizer, &_settings, this);
}
// call all "runSimplifiedChecks" in all registered Check classes
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
if (_settings.terminated())
return;
Timer timerSimpleChecks((*it)->name() + "::runSimplifiedChecks", _settings._showtime, &S_timerResults);
(*it)->runSimplifiedChecks(&_tokenizer, &_settings, this);
}
#ifdef HAVE_RULES #ifdef HAVE_RULES
// Are there extra rules? // Are there extra rules?
if (!_settings.rules.empty()) { if (!_settings.rules.empty()) {
std::ostringstream ostr; std::ostringstream ostr;
for (const Token *tok = _tokenizer.tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str(); ostr << " " << tok->str();
const std::string str(ostr.str()); const std::string str(ostr.str());
for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) { for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
const Settings::Rule &rule = *it; const Settings::Rule &rule = *it;
if (rule.pattern.empty() || rule.id.empty() || rule.severity.empty()) if (rule.pattern.empty() || rule.id.empty() || rule.severity.empty())
continue; continue;
const char *error = 0; const char *error = 0;
int erroffset = 0; int erroffset = 0;
pcre *re = pcre_compile(rule.pattern.c_str(),0,&error,&erroffset,NULL); pcre *re = pcre_compile(rule.pattern.c_str(),0,&error,&erroffset,NULL);
if (!re && error) { if (!re && error) {
ErrorLogger::ErrorMessage errmsg(std::list<ErrorLogger::ErrorMessage::FileLocation>(), ErrorLogger::ErrorMessage errmsg(std::list<ErrorLogger::ErrorMessage::FileLocation>(),
Severity::error, Severity::error,
error, error,
"pcre_compile", "pcre_compile",
false); false);
reportErr(errmsg); reportErr(errmsg);
} }
if (!re) if (!re)
continue; continue;
int pos = 0; int pos = 0;
int ovector[30]; int ovector[30];
while (0 <= pcre_exec(re, NULL, str.c_str(), (int)str.size(), pos, 0, ovector, 30)) { while (0 <= pcre_exec(re, NULL, str.c_str(), (int)str.size(), pos, 0, ovector, 30)) {
unsigned int pos1 = (unsigned int)ovector[0]; unsigned int pos1 = (unsigned int)ovector[0];
unsigned int pos2 = (unsigned int)ovector[1]; unsigned int pos2 = (unsigned int)ovector[1];
// jump to the end of the match for the next pcre_exec // jump to the end of the match for the next pcre_exec
pos = (int)pos2; pos = (int)pos2;
// determine location.. // determine location..
ErrorLogger::ErrorMessage::FileLocation loc; ErrorLogger::ErrorMessage::FileLocation loc;
loc.setfile(_tokenizer.getFiles()->front()); loc.setfile(_tokenizer.getFiles()->front());
loc.line = 0; loc.line = 0;
unsigned int len = 0; unsigned int len = 0;
for (const Token *tok = _tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer.tokens(); tok; tok = tok->next()) {
len = len + 1 + tok->str().size(); len = len + 1 + tok->str().size();
if (len > pos1) { if (len > pos1) {
loc.setfile(_tokenizer.getFiles()->at(tok->fileIndex())); loc.setfile(_tokenizer.getFiles()->at(tok->fileIndex()));
loc.line = tok->linenr(); loc.line = tok->linenr();
break; break;
}
} }
const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack(1, loc);
// Create error message
std::string summary;
if (rule.summary.empty())
summary = "found '" + str.substr(pos1, pos2 - pos1) + "'";
else
summary = rule.summary;
const ErrorLogger::ErrorMessage errmsg(callStack, Severity::fromString(rule.severity), summary, rule.id, false);
// Report error
reportErr(errmsg);
} }
const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack(1, loc); pcre_free(re);
// Create error message
std::string summary;
if (rule.summary.empty())
summary = "found '" + str.substr(pos1, pos2 - pos1) + "'";
else
summary = rule.summary;
const ErrorLogger::ErrorMessage errmsg(callStack, Severity::fromString(rule.severity), summary, rule.id, false);
// Report error
reportErr(errmsg);
} }
pcre_free(re);
} }
}
#endif #endif
} catch (const Token &tok) {
// Catch exception from Token class
const std::string fixedpath = Path::toNativeSeparators(_tokenizer.file(&tok));
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
ErrorLogger::ErrorMessage::FileLocation loc2;
loc2.setfile(Path::toNativeSeparators(FileName));
locationList.push_back(loc2);
ErrorLogger::ErrorMessage::FileLocation loc;
loc.line = tok.linenr();
loc.setfile(fixedpath);
locationList.push_back(loc);
const ErrorLogger::ErrorMessage errmsg(locationList,
Severity::error,
"Internal error. Token::Match called with varid 0.",
"cppcheckError",
false);
_errorLogger.reportErr(errmsg);
}
} }
Settings &CppCheck::settings() Settings &CppCheck::settings()

View File

@ -542,7 +542,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
"Internal error. Token::Match called with varid 0.", "Internal error. Token::Match called with varid 0.",
"cppcheckError", "cppcheckError",
false); false);
throw errmsg; throw *tok;
} }
if (tok->varId() != varid) if (tok->varId() != varid)

View File

@ -279,7 +279,7 @@ private:
givenACodeSampleToTokenize var("int a ; int b ;"); givenACodeSampleToTokenize var("int a ; int b ;");
// Varid == 0 should throw exception // Varid == 0 should throw exception
ASSERT_THROW(Token::Match(var.tokens(), "%type% %varid% ; %type% %var%", 0),ErrorLogger::ErrorMessage); ASSERT_THROW(Token::Match(var.tokens(), "%type% %varid% ; %type% %var%", 0),Token);
ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %varid% ; %type% %var%", 1)); ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %varid% ; %type% %var%", 1));
ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %var% ; %type% %varid%", 2)); ASSERT_EQUALS(true, Token::Match(var.tokens(), "%type% %var% ; %type% %varid%", 2));