Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str

if (!hasValidConfig && currCfg == *configurations.rbegin()) {
// If there is no valid configuration then report error..
preprocessor.error(o.location.file(), o.location.line, o.msg, o.type);
preprocessor.error(o.location.file(), o.location.line, o.location.col, o.msg, o.type);
}
continue;

Expand Down
51 changes: 32 additions & 19 deletions lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ Preprocessor::Preprocessor(simplecpp::TokenList& tokens, const Settings& setting

namespace {
struct BadInlineSuppression {
BadInlineSuppression(std::string file, const int line, std::string msg) : file(std::move(file)), line(line), errmsg(std::move(msg)) {}
BadInlineSuppression(std::string file, const int line, unsigned int col, std::string msg) : file(std::move(file)), line(line), col(col), errmsg(std::move(msg)) {}
std::string file;
int line;
int line; // TODO: needs to be unsigned
unsigned int col;
std::string errmsg;
};
}
Expand Down Expand Up @@ -143,7 +144,7 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
}

if (!errmsg.empty())
bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
bad.emplace_back(tok->location.file(), tok->location.line, tok->location.col, std::move(errmsg));

std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](const SuppressionList::Suppression& s) {
return !s.errorId.empty();
Expand All @@ -163,7 +164,7 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
inlineSuppressions.push_back(std::move(s));

if (!errmsg.empty())
bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
bad.emplace_back(tok->location.file(), tok->location.line, tok->location.col, std::move(errmsg));
}

return true;
Expand Down Expand Up @@ -272,7 +273,7 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett

if (throwError) {
// NOLINTNEXTLINE(bugprone-use-after-move) - moved only when thrownError is false
bad.emplace_back(suppr.fileName, suppr.lineNumber, "Suppress End: No matching begin");
bad.emplace_back(suppr.fileName, suppr.lineNumber, 0, "Suppress End: No matching begin"); // TODO: set column
}
} else if (SuppressionList::Type::unique == suppr.type || suppr.type == SuppressionList::Type::macro) {
// special handling when suppressing { warnings for backwards compatibility
Expand All @@ -292,14 +293,14 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett
if (onlyComments)
suppressions.addSuppression(std::move(suppr)); // TODO: check result
else
bad.emplace_back(suppr.fileName, suppr.lineNumber, "File suppression should be at the top of the file");
bad.emplace_back(suppr.fileName, suppr.lineNumber, 0, "File suppression should be at the top of the file"); // TODO: set column
}
}
}

for (const SuppressionList::Suppression & suppr: inlineSuppressionsBlockBegin)
// cppcheck-suppress useStlAlgorithm
bad.emplace_back(suppr.fileName, suppr.lineNumber, "Suppress Begin: No matching end");
bad.emplace_back(suppr.fileName, suppr.lineNumber, 0, "Suppress Begin: No matching end"); // TODO: set column
}

void Preprocessor::inlineSuppressions(SuppressionList &suppressions)
Expand All @@ -312,7 +313,7 @@ void Preprocessor::inlineSuppressions(SuppressionList &suppressions)
::addInlineSuppressions(filedata->tokens, mSettings, suppressions, err);
}
for (const BadInlineSuppression &bad : err) {
error(bad.file, bad.line, bad.errmsg, simplecpp::Output::ERROR); // TODO: use individual (non-fatal) ID
invalidSuppression(bad.file, bad.line, bad.col, bad.errmsg); // TODO: column is always 0
}
}

Expand Down Expand Up @@ -860,7 +861,7 @@ bool Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
case simplecpp::Output::ERROR:
hasError = true;
if (!startsWith(out.msg,"#error") || showerror)
error(out.location.file(), out.location.line, out.msg, out.type);
error(out.location.file(), out.location.line, out.location.col, out.msg, out.type);
break;
case simplecpp::Output::WARNING:
case simplecpp::Output::PORTABILITY_BACKSLASH:
Expand All @@ -877,13 +878,13 @@ bool Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
case simplecpp::Output::SYNTAX_ERROR:
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
hasError = true;
error(out.location.file(), out.location.line, out.msg, out.type);
error(out.location.file(), out.location.line, out.location.col, out.msg, out.type);
break;
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
case simplecpp::Output::FILE_NOT_FOUND:
case simplecpp::Output::DUI_ERROR:
hasError = true;
error("", 0, out.msg, out.type);
error("", 0, 0, out.msg, out.type);
break;
}
}
Expand Down Expand Up @@ -918,21 +919,26 @@ static std::string simplecppErrToId(simplecpp::Output::Type type)
cppcheck::unreachable();
}

void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg, simplecpp::Output::Type type)
void Preprocessor::error(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg, simplecpp::Output::Type type)
{
error(filename, linenr, col, msg, simplecppErrToId(type));
}

void Preprocessor::error(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg, const std::string& id)
{
std::list<ErrorMessage::FileLocation> locationList;
if (!filename.empty()) {
std::string file = Path::fromNativeSeparators(filename);
if (mSettings.relativePaths)
file = Path::getRelativePath(file, mSettings.basePaths);

locationList.emplace_back(file, linenr, 0); // TODO: set column
locationList.emplace_back(file, linenr, col);
}
mErrorLogger.reportErr(ErrorMessage(std::move(locationList),
mFile0,
Severity::error,
msg,
simplecppErrToId(type),
id,
Certainty::normal));
}

Expand All @@ -944,6 +950,7 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line

std::list<ErrorMessage::FileLocation> locationList;
if (!filename.empty()) {
// TODO: add relative path handling?
locationList.emplace_back(filename, linenr, col);
}
ErrorMessage errmsg(std::move(locationList), mFile0, Severity::information,
Expand All @@ -955,18 +962,24 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line
mErrorLogger.reportErr(errmsg);
}

void Preprocessor::invalidSuppression(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg)
{
error(filename, linenr, col, msg, "invalidSuppression");
}

void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &settings)
{
std::vector<std::string> files;
simplecpp::TokenList tokens(files);
Preprocessor preprocessor(tokens, settings, errorLogger, Standards::Language::CPP);
preprocessor.missingInclude("", 1, 2, "", UserHeader);
preprocessor.missingInclude("", 1, 2, "", SystemHeader);
preprocessor.error("", 1, "message", simplecpp::Output::ERROR);
preprocessor.error("", 1, "message", simplecpp::Output::SYNTAX_ERROR);
preprocessor.error("", 1, "message", simplecpp::Output::UNHANDLED_CHAR_ERROR);
preprocessor.error("", 1, "message", simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY);
preprocessor.error("", 1, "message", simplecpp::Output::FILE_NOT_FOUND);
preprocessor.error("", 1, 2, "message", simplecpp::Output::ERROR);
preprocessor.error("", 1, 2, "message", simplecpp::Output::SYNTAX_ERROR);
preprocessor.error("", 1, 2, "message", simplecpp::Output::UNHANDLED_CHAR_ERROR);
preprocessor.error("", 1, 2, "message", simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY);
preprocessor.error("", 1, 2, "message", simplecpp::Output::FILE_NOT_FOUND);
preprocessor.invalidSuppression("", 1, 2, "message");
}

void Preprocessor::dump(std::ostream &out) const
Expand Down
4 changes: 3 additions & 1 deletion lib/preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {

bool reportOutput(const simplecpp::OutputList &outputList, bool showerror);

void error(const std::string &filename, unsigned int linenr, const std::string &msg, simplecpp::Output::Type type);
void error(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg, simplecpp::Output::Type type);

private:
static bool hasErrors(const simplecpp::Output &output);
Expand All @@ -160,6 +160,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
};

void missingInclude(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &header, HeaderTypes headerType);
void invalidSuppression(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg);
void error(const std::string &filename, unsigned int linenr, unsigned int col, const std::string &msg, const std::string& id);

void addRemarkComments(const simplecpp::TokenList &tokens, std::vector<RemarkComment> &remarkComments) const;

Expand Down
4 changes: 2 additions & 2 deletions lib/suppressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class CPPCHECKLIB SuppressionList {
const std::string &getFileName() const {
return mFileName;
}
int lineNumber;
int lineNumber; // TODO: need to be unsigned
Certainty certainty;
std::string symbolNames;
std::set<std::string> macroNames;
Expand Down Expand Up @@ -149,7 +149,7 @@ class CPPCHECKLIB SuppressionList {
std::string errorId;
std::string fileName;
std::string extraComment;
int lineNumber = NO_LINE;
int lineNumber = NO_LINE; // TODO: needs to be unsigned
int lineBegin = NO_LINE;
int lineEnd = NO_LINE;
Type type = Type::unique;
Expand Down
16 changes: 6 additions & 10 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3429,8 +3429,7 @@ def test_preprocess_enforced_cpp(tmp_path): # #10989
assert exitcode == 0, stdout if stdout else stderr
assert stdout.splitlines() == []
assert stderr.splitlines() == [
# TODO: lacks column information
'{}:2:0: error: #error "err" [preprocessorErrorDirective]'.format(test_file)
'{}:2:2: error: #error "err" [preprocessorErrorDirective]'.format(test_file)
]


Expand Down Expand Up @@ -3889,8 +3888,7 @@ def test_simplecpp_unhandled_char(tmp_path):
assert exitcode == 0, stdout
assert stdout.splitlines() == []
assert stderr.splitlines() == [
# TODO: lacks column information
'{}:2:0: error: The code contains unhandled character(s) (character code=228). Neither unicode nor extended ascii is supported. [unhandledChar]'.format(test_file)
'{}:2:5: error: The code contains unhandled character(s) (character code=228). Neither unicode nor extended ascii is supported. [unhandledChar]'.format(test_file)
]


Expand Down Expand Up @@ -3921,9 +3919,8 @@ def test_simplecpp_include_nested_too_deeply(tmp_path):
test_h = tmp_path / 'test_398.h'
assert stderr.splitlines() == [
# TODO: should only report the error once
# TODO: lacks column information
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h),
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h)
'{}:1:2: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h),
'{}:1:2: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h)
]


Expand All @@ -3944,7 +3941,6 @@ def test_simplecpp_syntax_error(tmp_path):
assert stdout.splitlines() == []
assert stderr.splitlines() == [
# TODO: should only report the error once
# TODO: lacks column information
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file),
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file)
'{}:1:2: error: No header in #include [syntaxError]'.format(test_file),
'{}:1:2: error: No header in #include [syntaxError]'.format(test_file)
]
Loading