Skip to content

Commit ea70b6a

Browse files
committed
fixed #14275 - map simplecpp errors to individual IDs [skip ci]
1 parent 09edac0 commit ea70b6a

File tree

8 files changed

+60
-31
lines changed

8 files changed

+60
-31
lines changed

lib/cppcheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
12131213

12141214
if (!hasValidConfig && currCfg == *configurations.rbegin()) {
12151215
// If there is no valid configuration then report error..
1216-
preprocessor.error(o.location.file(), o.location.line, o.msg);
1216+
preprocessor.error(o.location.file(), o.location.line, o.msg, o.type);
12171217
}
12181218
continue;
12191219

lib/errorlogger.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
const std::set<std::string> ErrorLogger::mCriticalErrorIds{
4646
"cppcheckError",
4747
"cppcheckLimit",
48+
"includeNestedTooDeeply",
4849
"internalAstError",
4950
"instantiationError",
5051
"internalError",
@@ -53,6 +54,7 @@ const std::set<std::string> ErrorLogger::mCriticalErrorIds{
5354
"premium-invalidLicense",
5455
"preprocessorErrorDirective",
5556
"syntaxError",
57+
"unhandledChar",
5658
"unknownMacro"
5759
};
5860

lib/preprocessor.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ void Preprocessor::inlineSuppressions(SuppressionList &suppressions)
312312
::addInlineSuppressions(filedata->tokens, mSettings, suppressions, err);
313313
}
314314
for (const BadInlineSuppression &bad : err) {
315-
error(bad.file, bad.line, bad.errmsg);
315+
error(bad.file, bad.line, bad.errmsg, simplecpp::Output::ERROR); // TODO: use individual (non-fatal) ID
316316
}
317317
}
318318

@@ -860,7 +860,7 @@ bool Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
860860
case simplecpp::Output::ERROR:
861861
hasError = true;
862862
if (!startsWith(out.msg,"#error") || showerror)
863-
error(out.location.file(), out.location.line, out.msg);
863+
error(out.location.file(), out.location.line, out.msg, out.type);
864864
break;
865865
case simplecpp::Output::WARNING:
866866
case simplecpp::Output::PORTABILITY_BACKSLASH:
@@ -877,21 +877,47 @@ bool Preprocessor::reportOutput(const simplecpp::OutputList &outputList, bool sh
877877
case simplecpp::Output::SYNTAX_ERROR:
878878
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
879879
hasError = true;
880-
error(out.location.file(), out.location.line, out.msg);
880+
error(out.location.file(), out.location.line, out.msg, out.type);
881881
break;
882882
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
883883
case simplecpp::Output::FILE_NOT_FOUND:
884884
case simplecpp::Output::DUI_ERROR:
885885
hasError = true;
886-
error("", 0, out.msg);
886+
error("", 0, out.msg, out.type);
887887
break;
888888
}
889889
}
890890

891891
return hasError;
892892
}
893893

894-
void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg)
894+
static std::string simplecppErrToId(simplecpp::Output::Type type)
895+
{
896+
switch (type) {
897+
case simplecpp::Output::ERROR:
898+
return "preprocessorErrorDirective";
899+
case simplecpp::Output::SYNTAX_ERROR:
900+
return "syntaxError";
901+
case simplecpp::Output::UNHANDLED_CHAR_ERROR:
902+
return "unhandledChar";
903+
case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
904+
return "includeNestedTooDeeply";
905+
// should never occur
906+
case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
907+
case simplecpp::Output::FILE_NOT_FOUND:
908+
case simplecpp::Output::DUI_ERROR:
909+
// handled separately
910+
case simplecpp::Output::MISSING_HEADER:
911+
// no handled at all (warnings)
912+
case simplecpp::Output::WARNING:
913+
case simplecpp::Output::PORTABILITY_BACKSLASH:
914+
throw std::runtime_error("unexpected simplecpp::Output type");
915+
}
916+
917+
cppcheck::unreachable();
918+
}
919+
920+
void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg, simplecpp::Output::Type type)
895921
{
896922
std::list<ErrorMessage::FileLocation> locationList;
897923
if (!filename.empty()) {
@@ -905,7 +931,7 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const
905931
mFile0,
906932
Severity::error,
907933
msg,
908-
"preprocessorErrorDirective",
934+
simplecppErrToId(type),
909935
Certainty::normal));
910936
}
911937

@@ -935,7 +961,10 @@ void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &se
935961
Preprocessor preprocessor(tokens, settings, errorLogger, Standards::Language::CPP);
936962
preprocessor.missingInclude("", 1, 2, "", UserHeader);
937963
preprocessor.missingInclude("", 1, 2, "", SystemHeader);
938-
preprocessor.error("", 1, "#error message"); // #error ..
964+
preprocessor.error("", 1, "message", simplecpp::Output::ERROR);
965+
preprocessor.error("", 1, "message", simplecpp::Output::SYNTAX_ERROR);
966+
preprocessor.error("", 1, "message", simplecpp::Output::UNHANDLED_CHAR_ERROR);
967+
preprocessor.error("", 1, "message", simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY);
939968
}
940969

941970
void Preprocessor::dump(std::ostream &out) const

lib/preprocessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
142142

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

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

147147
private:
148148
static bool hasErrors(const simplecpp::Output &output);

releasenotes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ GUI:
1313
-
1414

1515
Changed interface:
16+
- some `preprocessorErrorDirective` and `syntaxError` errors got more specific error IDs.
1617
-
1718

1819
Deprecations:

test/cli/other_test.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3890,8 +3890,7 @@ def test_simplecpp_unhandled_char(tmp_path):
38903890
assert stdout.splitlines() == []
38913891
assert stderr.splitlines() == [
38923892
# TODO: lacks column information
3893-
# TODO: should report another ID
3894-
'{}:2:0: error: The code contains unhandled character(s) (character code=228). Neither unicode nor extended ascii is supported. [preprocessorErrorDirective]'.format(test_file)
3893+
'{}:2:0: error: The code contains unhandled character(s) (character code=228). Neither unicode nor extended ascii is supported. [unhandledChar]'.format(test_file)
38953894
]
38963895

38973896

@@ -3922,10 +3921,9 @@ def test_simplecpp_include_nested_too_deeply(tmp_path):
39223921
test_h = tmp_path / 'test_398.h'
39233922
assert stderr.splitlines() == [
39243923
# TODO: should only report the error once
3925-
# TODO: should report another ID
39263924
# TODO: lacks column information
3927-
'{}:1:0: error: #include nested too deeply [preprocessorErrorDirective]'.format(test_h),
3928-
'{}:1:0: error: #include nested too deeply [preprocessorErrorDirective]'.format(test_h)
3925+
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h),
3926+
'{}:1:0: error: #include nested too deeply [includeNestedTooDeeply]'.format(test_h)
39293927
]
39303928

39313929

@@ -3946,8 +3944,7 @@ def test_simplecpp_syntax_error(tmp_path):
39463944
assert stdout.splitlines() == []
39473945
assert stderr.splitlines() == [
39483946
# TODO: should only report the error once
3949-
# TODO: should report another ID
39503947
# TODO: lacks column information
3951-
'{}:1:0: error: No header in #include [preprocessorErrorDirective]'.format(test_file),
3952-
'{}:1:0: error: No header in #include [preprocessorErrorDirective]'.format(test_file)
3948+
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file),
3949+
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file)
39533950
]

test/testpreprocessor.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,7 @@ class TestPreprocessor : public TestFixture {
15291529
const std::map<std::string, std::string> actual = getcode(settings0, *this, filedata);
15301530

15311531
ASSERT_EQUALS(0, actual.size());
1532-
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());
1532+
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());
15331533
}
15341534
}
15351535

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

15461546
ASSERT_EQUALS("", actual);
1547-
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());
1547+
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());
15481548
}
15491549

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

15591559
ASSERT_EQUALS("", actual);
1560-
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());
1560+
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());
15611561
}
15621562

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

15721572
ASSERT_EQUALS("", actual);
1573-
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());
1573+
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());
15741574
}
15751575

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

15841584
ASSERT_EQUALS("", actual);
1585-
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());
1585+
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());
15861586
}
15871587

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

1601-
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());
1601+
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());
16021602
}
16031603
}
16041604

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

16571657
void newline_in_macro() {
@@ -1968,12 +1968,12 @@ class TestPreprocessor : public TestFixture {
19681968

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

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

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

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

23752375
void garbage() {
@@ -2631,7 +2631,7 @@ class TestPreprocessor : public TestFixture {
26312631

26322632
settings.standards.setStd("c++11");
26332633
ASSERT_EQUALS("", getcodeforcfg(settings, *this, code, "", "test.cpp"));
2634-
ASSERT_EQUALS("[test.cpp:1:0]: (error) failed to evaluate #if condition, undefined function-like macro invocation: __has_include( ... ) [preprocessorErrorDirective]\n", errout_str());
2634+
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
26352635

26362636
settings.standards.setStd("c++17");
26372637
ASSERT_EQUALS("", getcodeforcfg(settings, *this, code, "", "test.cpp"));

test/testsuppressions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ class TestSuppressions : public TestFixture {
13551355
"[!VAR \"BC\" = \"$BC + 1\"!][!//\n"
13561356
"[!ENDIF!][!//\n"
13571357
"};";
1358-
ASSERT_EQUALS(0, (this->*check)(code, "preprocessorErrorDirective:test.cpp:4"));
1358+
ASSERT_EQUALS(0, (this->*check)(code, "syntaxError:test.cpp:4"));
13591359
ASSERT_EQUALS("", errout_str());
13601360
}
13611361

0 commit comments

Comments
 (0)