Skip to content
Merged
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);
preprocessor.error(o.location.file(), o.location.line, o.msg, o.type);
}
continue;

Expand Down
2 changes: 1 addition & 1 deletion lib/cppcheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class CPPCHECKLIB CppCheck {
* @brief Check a file using stream
* @param file the file
* @param cfgname cfg name
* @param createTokenList a function to create the simplecpp::TokenList with
* @param createTokenList a function to create the simplecpp::TokenList with - throws simplecpp::Output
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment might have been wrong. The errorhandling code confuses me so I flip-flop on comments in my local changes. Will amend in upcoming changes if necessary.

* @return number of errors found
*/
unsigned int checkInternal(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const CreateTokenListFn& createTokenList);
Expand Down
3 changes: 3 additions & 0 deletions lib/errorlogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,17 @@
const std::set<std::string> ErrorLogger::mCriticalErrorIds{
"cppcheckError",
"cppcheckLimit",
"includeNestedTooDeeply",
"internalAstError",
"instantiationError",
"internalError",
"missingFile",
"premium-internalError",
"premium-invalidArgument",
"premium-invalidLicense",
"preprocessorErrorDirective",
"syntaxError",
"unhandledChar",
"unknownMacro"
};

Expand Down
45 changes: 38 additions & 7 deletions lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ void Preprocessor::inlineSuppressions(SuppressionList &suppressions)
::addInlineSuppressions(filedata->tokens, mSettings, suppressions, err);
}
for (const BadInlineSuppression &bad : err) {
error(bad.file, bad.line, bad.errmsg);
error(bad.file, bad.line, bad.errmsg, simplecpp::Output::ERROR); // TODO: use individual (non-fatal) ID
}
}

Expand Down Expand Up @@ -860,7 +860,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);
error(out.location.file(), out.location.line, out.msg, out.type);
break;
case simplecpp::Output::WARNING:
case simplecpp::Output::PORTABILITY_BACKSLASH:
Expand All @@ -877,21 +877,48 @@ 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);
error(out.location.file(), out.location.line, 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);
error("", 0, out.msg, out.type);
break;
}
}

return hasError;
}

void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg)
static std::string simplecppErrToId(simplecpp::Output::Type type)
{
switch (type) {
case simplecpp::Output::ERROR:
return "preprocessorErrorDirective";
case simplecpp::Output::SYNTAX_ERROR:
return "syntaxError";
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
return "unhandledChar";
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
return "includeNestedTooDeeply";
case simplecpp::Output::FILE_NOT_FOUND:
return "missingFile";
// should never occur
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
case simplecpp::Output::DUI_ERROR:
// handled separately
case simplecpp::Output::MISSING_HEADER:
// no handled at all (warnings)
case simplecpp::Output::WARNING:
case simplecpp::Output::PORTABILITY_BACKSLASH:
throw std::runtime_error("unexpected simplecpp::Output type " + std::to_string(type));
}

cppcheck::unreachable();
}

void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg, simplecpp::Output::Type type)
{
std::list<ErrorMessage::FileLocation> locationList;
if (!filename.empty()) {
Expand All @@ -905,7 +932,7 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const
mFile0,
Severity::error,
msg,
"preprocessorErrorDirective",
simplecppErrToId(type),
Certainty::normal));
}

Expand Down Expand Up @@ -935,7 +962,11 @@ void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &se
Preprocessor preprocessor(tokens, settings, errorLogger, Standards::Language::CPP);
preprocessor.missingInclude("", 1, 2, "", UserHeader);
preprocessor.missingInclude("", 1, 2, "", SystemHeader);
preprocessor.error("", 1, "#error message"); // #error ..
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);
}

void Preprocessor::dump(std::ostream &out) const
Expand Down
2 changes: 1 addition & 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);
void error(const std::string &filename, unsigned int linenr, const std::string &msg, simplecpp::Output::Type type);

private:
static bool hasErrors(const simplecpp::Output &output);
Expand Down
1 change: 1 addition & 0 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ GUI:
-

Changed interface:
- some `preprocessorErrorDirective` and `syntaxError` errors got more specific error IDs.
-

Deprecations:
Expand Down
13 changes: 5 additions & 8 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3890,8 +3890,7 @@ def test_simplecpp_unhandled_char(tmp_path):
assert stdout.splitlines() == []
assert stderr.splitlines() == [
# TODO: lacks column information
# TODO: should report another ID
'{}:2:0: error: The code contains unhandled character(s) (character code=228). Neither unicode nor extended ascii is supported. [preprocessorErrorDirective]'.format(test_file)
'{}:2:0: 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 @@ -3922,10 +3921,9 @@ 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: should report another ID
# TODO: lacks column information
'{}:1:0: error: #include nested too deeply [preprocessorErrorDirective]'.format(test_h),
'{}:1:0: error: #include nested too deeply [preprocessorErrorDirective]'.format(test_h)
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h),
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h)
]


Expand All @@ -3946,8 +3944,7 @@ def test_simplecpp_syntax_error(tmp_path):
assert stdout.splitlines() == []
assert stderr.splitlines() == [
# TODO: should only report the error once
# TODO: should report another ID
# TODO: lacks column information
'{}:1:0: error: No header in #include [preprocessorErrorDirective]'.format(test_file),
'{}:1:0: error: No header in #include [preprocessorErrorDirective]'.format(test_file)
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file),
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file)
]
2 changes: 1 addition & 1 deletion test/cli/project_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def test_json_entry_file_not_found(tmpdir):
"--project=" + str(project_file)
])
assert 0 == ret
assert stderr == f"nofile:0:0: error: File is missing: {missing_file_posix} [preprocessorErrorDirective]\n"
assert stderr == f"nofile:0:0: error: File is missing: {missing_file_posix} [missingFile]\n"


def test_json_no_arguments(tmpdir):
Expand Down
26 changes: 13 additions & 13 deletions test/testpreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ class TestPreprocessor : public TestFixture {
const std::map<std::string, std::string> actual = getcode(settings0, *this, filedata);

ASSERT_EQUALS(0, actual.size());
ASSERT_EQUALS("[file.c:2:0]: (error) No pair for character ('). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.c:2:0]: (error) No pair for character ('). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}
}

Expand All @@ -1544,7 +1544,7 @@ class TestPreprocessor : public TestFixture {
const std::string actual(expandMacros(filedata, *this));

ASSERT_EQUALS("", actual);
ASSERT_EQUALS("[file.cpp:3:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.cpp:3:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}

{
Expand All @@ -1557,7 +1557,7 @@ class TestPreprocessor : public TestFixture {
const std::string actual(expandMacros(filedata, *this));

ASSERT_EQUALS("", actual);
ASSERT_EQUALS("[abc.h:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[abc.h:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}

{
Expand All @@ -1570,7 +1570,7 @@ class TestPreprocessor : public TestFixture {
const std::string actual(expandMacros(filedata, *this));

ASSERT_EQUALS("", actual);
ASSERT_EQUALS("[file.cpp:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.cpp:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}

{
Expand All @@ -1582,7 +1582,7 @@ class TestPreprocessor : public TestFixture {
const std::string actual(expandMacros(filedata, *this));

ASSERT_EQUALS("", actual);
ASSERT_EQUALS("[file.cpp:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.cpp:2:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}

{
Expand All @@ -1598,7 +1598,7 @@ class TestPreprocessor : public TestFixture {
// expand macros..
(void)expandMacros(filedata, *this);

ASSERT_EQUALS("[file.cpp:7:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.cpp:7:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str());
}
}

Expand Down Expand Up @@ -1651,7 +1651,7 @@ class TestPreprocessor : public TestFixture {
// Compare results..
ASSERT_EQUALS(1, actual.size());
ASSERT_EQUALS("", actual.at(""));
ASSERT_EQUALS("[file.c:6:0]: (error) failed to expand 'BC', Wrong number of parameters for macro 'BC'. [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.c:6:0]: (error) failed to expand 'BC', Wrong number of parameters for macro 'BC'. [syntaxError]\n", errout_str());
}

void newline_in_macro() {
Expand Down Expand Up @@ -1968,12 +1968,12 @@ class TestPreprocessor : public TestFixture {

void invalid_define_1() {
(void)getcode(settings0, *this, "#define =\n");
ASSERT_EQUALS("[file.c:1:0]: (error) Failed to parse #define [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.c:1:0]: (error) Failed to parse #define [syntaxError]\n", errout_str());
}

void invalid_define_2() { // #4036
(void)getcode(settings0, *this, "#define () {(int f(x) }\n");
ASSERT_EQUALS("[file.c:1:0]: (error) Failed to parse #define [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[file.c:1:0]: (error) Failed to parse #define [syntaxError]\n", errout_str());
}

void inline_suppressions() {
Expand Down Expand Up @@ -2119,7 +2119,7 @@ class TestPreprocessor : public TestFixture {
const char code[] = "#elif (){\n";
const std::string actual = getcodeforcfg(settings0, *this, code, "TEST", "test.c");
ASSERT_EQUALS("", actual);
ASSERT_EQUALS("[test.c:1:0]: (error) #elif without #if [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[test.c:1:0]: (error) #elif without #if [syntaxError]\n", errout_str());
}

void getConfigs1() {
Expand Down Expand Up @@ -2368,8 +2368,8 @@ class TestPreprocessor : public TestFixture {
// Preprocess => don't crash..
(void)getcode(settings0, *this, filedata);
ASSERT_EQUALS(
"[file.c:1:0]: (error) Syntax error in #ifdef [preprocessorErrorDirective]\n"
"[file.c:1:0]: (error) Syntax error in #ifdef [preprocessorErrorDirective]\n", errout_str());
"[file.c:1:0]: (error) Syntax error in #ifdef [syntaxError]\n"
"[file.c:1:0]: (error) Syntax error in #ifdef [syntaxError]\n", errout_str());
}

void garbage() {
Expand Down Expand Up @@ -2631,7 +2631,7 @@ class TestPreprocessor : public TestFixture {

settings.standards.setStd("c++11");
ASSERT_EQUALS("", getcodeforcfg(settings, *this, code, "", "test.cpp"));
ASSERT_EQUALS("[test.cpp:1:0]: (error) failed to evaluate #if condition, undefined function-like macro invocation: __has_include( ... ) [preprocessorErrorDirective]\n", errout_str());
ASSERT_EQUALS("[test.cpp:1:0]: (error) failed to evaluate #if condition, undefined function-like macro invocation: __has_include( ... ) [syntaxError]\n", errout_str()); // TODO: use individual ID

settings.standards.setStd("c++17");
ASSERT_EQUALS("", getcodeforcfg(settings, *this, code, "", "test.cpp"));
Expand Down
2 changes: 1 addition & 1 deletion test/testsuppressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ class TestSuppressions : public TestFixture {
"[!VAR \"BC\" = \"$BC + 1\"!][!//\n"
"[!ENDIF!][!//\n"
"};";
ASSERT_EQUALS(0, (this->*check)(code, "preprocessorErrorDirective:test.cpp:4"));
ASSERT_EQUALS(0, (this->*check)(code, "syntaxError:test.cpp:4"));
ASSERT_EQUALS("", errout_str());
}

Expand Down
Loading