Skip to content

Commit 33ff194

Browse files
authored
Fix #13825 (toomanyconfigs lacks file information) (danmar#7967)
The file-less warning generated from cppcheckexecutor.cpp is removed. the --errorlist message should match the real message.
1 parent 1ca1246 commit 33ff194

File tree

5 files changed

+56
-69
lines changed

5 files changed

+56
-69
lines changed

cli/cppcheckexecutor.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,6 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
432432
returnValue = settings.exitCode;
433433
}
434434

435-
if (!settings.checkConfiguration) {
436-
cppcheck.tooManyConfigsError("",0U);
437-
}
438-
439435
stdLogger.writeCheckersReport(supprs);
440436

441437
if (settings.outputFormat == Settings::OutputFormat::xml) {

lib/cppcheck.cpp

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,9 @@ std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const std:
857857
toolinfo << (mSettings.severity.isEnabled(Severity::portability) ? 'p' : ' ');
858858
toolinfo << (mSettings.severity.isEnabled(Severity::information) ? 'i' : ' ');
859859
toolinfo << mSettings.userDefines;
860+
toolinfo << (mSettings.checkConfiguration ? 'c' : ' '); // --check-config
861+
toolinfo << (mSettings.force ? 'f' : ' ');
862+
toolinfo << mSettings.maxConfigs;
860863
toolinfo << std::to_string(static_cast<std::uint8_t>(mSettings.checkLevel));
861864
for (const auto &a : mSettings.addonInfos) {
862865
toolinfo << a.name;
@@ -1041,6 +1044,9 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10411044
for (const std::string &config : configurations)
10421045
(void)preprocessor.getcode(config, files, false);
10431046

1047+
if (configurations.size() > mSettings.maxConfigs)
1048+
tooManyConfigsError(Path::toNativeSeparators(file.spath()), configurations.size());
1049+
10441050
if (analyzerInformation)
10451051
mLogger->setAnalyzerInfo(nullptr);
10461052
return 0;
@@ -1060,14 +1066,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10601066
}
10611067
#endif
10621068

1063-
if (!mSettings.force && configurations.size() > mSettings.maxConfigs) {
1064-
if (mSettings.severity.isEnabled(Severity::information)) {
1065-
tooManyConfigsError(Path::toNativeSeparators(file.spath()),configurations.size());
1066-
} else {
1067-
mTooManyConfigs = true;
1068-
}
1069-
}
1070-
10711069
FilesDeleter filesDeleter;
10721070

10731071
// write dump file xml prolog
@@ -1092,8 +1090,18 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10921090

10931091
// Check only a few configurations (default 12), after that bail out, unless --force
10941092
// was used.
1095-
if (!mSettings.force && ++checkCount > mSettings.maxConfigs)
1093+
if (!mSettings.force && ++checkCount > mSettings.maxConfigs) {
1094+
// If maxConfigs has default value then report information message that configurations are skipped.
1095+
// If maxConfigs does not have default value then the user is explicitly skipping configurations so
1096+
// the information message is not reported, the whole purpose of setting i.e. --max-configs=1 is to
1097+
// skip configurations. When --check-config is used then tooManyConfigs will be reported even if the
1098+
// value is non-default.
1099+
const Settings defaultSettings;
1100+
if (mSettings.maxConfigs == defaultSettings.maxConfigs && mSettings.severity.isEnabled(Severity::information))
1101+
tooManyConfigsError(Path::toNativeSeparators(file.spath()), configurations.size());
1102+
10961103
break;
1104+
}
10971105

10981106
std::string currentConfig;
10991107

@@ -1630,32 +1638,14 @@ void CppCheck::executeAddonsWholeProgram(const std::list<FileWithDetails> &files
16301638

16311639
void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfConfigurations)
16321640
{
1633-
if (!mSettings.severity.isEnabled(Severity::information) && !mTooManyConfigs)
1634-
return;
1635-
1636-
mTooManyConfigs = false;
1637-
1638-
if (mSettings.severity.isEnabled(Severity::information) && file.empty())
1639-
return;
1640-
16411641
std::list<ErrorMessage::FileLocation> loclist;
16421642
if (!file.empty()) {
16431643
loclist.emplace_back(file, 0, 0);
16441644
}
16451645

16461646
std::ostringstream msg;
1647-
msg << "Too many #ifdef configurations - cppcheck only checks " << mSettings.maxConfigs;
1648-
if (numberOfConfigurations > mSettings.maxConfigs)
1649-
msg << " of " << numberOfConfigurations << " configurations. Use --force to check all configurations.\n";
1650-
if (file.empty())
1651-
msg << " configurations. Use --force to check all configurations. For more details, use --enable=information.\n";
1652-
msg << "The checking of the file will be interrupted because there are too many "
1653-
"#ifdef configurations. Checking of all #ifdef configurations can be forced "
1654-
"by --force command line option or from GUI preferences. However that may "
1655-
"increase the checking time.";
1656-
if (file.empty())
1657-
msg << " For more details, use --enable=information.";
1658-
1647+
msg << "Too many #ifdef configurations - cppcheck only checks " << mSettings.maxConfigs
1648+
<< " of " << numberOfConfigurations << " configurations. Use --force to check all configurations.";
16591649

16601650
ErrorMessage errmsg(std::move(loclist),
16611651
"",
@@ -1669,8 +1659,6 @@ void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfCo
16691659

16701660
void CppCheck::purgedConfigurationMessage(const std::string &file, const std::string& configuration)
16711661
{
1672-
mTooManyConfigs = false;
1673-
16741662
if (mSettings.severity.isEnabled(Severity::information) && file.empty())
16751663
return;
16761664

@@ -1699,7 +1687,6 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger)
16991687

17001688
CppCheck cppcheck(settings, supprs, errorlogger, true, nullptr);
17011689
cppcheck.purgedConfigurationMessage("","");
1702-
cppcheck.mTooManyConfigs = true;
17031690
cppcheck.tooManyConfigsError("",0U);
17041691
// TODO: add functions to get remaining error messages
17051692

lib/cppcheck.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,6 @@ class CPPCHECKLIB CppCheck {
249249

250250
bool mUseGlobalSuppressions;
251251

252-
/** Are there too many configs? */
253-
bool mTooManyConfigs{};
254-
255252
/** File info used for whole program analysis */
256253
std::list<Check::FileInfo*> mFileInfo;
257254

test/cli/other_test.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3948,3 +3948,40 @@ def test_simplecpp_syntax_error(tmp_path):
39483948
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file),
39493949
'{}:1:0: error: No header in #include [syntaxError]'.format(test_file)
39503950
]
3951+
3952+
3953+
@pytest.mark.parametrize('max_configs,number_of_configs,check_config,expected_warn', [
3954+
# max configs = default, max configs < number of configs => warn
3955+
(12, 20, False, True),
3956+
(12, 20, True, True),
3957+
3958+
# max configs != default, max configs < number of configs => warn if --check-config
3959+
(6, 20, False, False),
3960+
(6, 20, True, True),
3961+
3962+
# max configs >= number of configs => no warning
3963+
(20, 20, False, False),
3964+
(20, 20, False, False)
3965+
])
3966+
def test_max_configs(tmp_path, max_configs, number_of_configs, check_config, expected_warn):
3967+
test_file = tmp_path / 'test.cpp'
3968+
with open(test_file, "w") as f:
3969+
for i in range(1,number_of_configs):
3970+
dir = 'if' if i == 1 else 'elif'
3971+
f.write(f'#{dir} defined(X{i})\nx = {i};\n')
3972+
f.write('#endif\n')
3973+
3974+
args = [f'--max-configs={max_configs}', '--enable=information', '--template=simple', str(test_file)]
3975+
3976+
if check_config:
3977+
args = ['--check-config'] + args
3978+
3979+
# default max configs is set to 12, warn if code contains more configurations than that
3980+
_, _, stderr = cppcheck(args)
3981+
if not expected_warn:
3982+
assert stderr.splitlines() == []
3983+
else:
3984+
assert stderr.splitlines() == [
3985+
'{}:0:0: information: Too many #ifdef configurations - cppcheck only checks {} of {} configurations. Use --force to check all configurations. [toomanyconfigs]'
3986+
.format(test_file, max_configs, number_of_configs)
3987+
]

test/testcppcheck.cpp

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ class TestCppcheck : public TestFixture {
8181
TEST_CASE(getDumpFileContentsLibrary);
8282
TEST_CASE(checkPlistOutput);
8383
TEST_CASE(premiumResultsCache);
84-
TEST_CASE(toomanyconfigs);
8584
TEST_CASE(purgedConfiguration);
8685
}
8786

@@ -594,35 +593,6 @@ class TestCppcheck : public TestFixture {
594593
ASSERT(hash1 != hash2);
595594
}
596595

597-
void toomanyconfigs() const
598-
{
599-
ScopedFile test_file_a("a.c",
600-
"#if DEF_1\n"
601-
"#endif\n"
602-
"#if DEF_2\n"
603-
"#endif\n"
604-
"#if DEF_3\n"
605-
"#endif");
606-
607-
// this is the "simple" format
608-
const auto s = dinit(Settings,
609-
$.templateFormat = templateFormat, // TODO: remove when we only longer rely on toString() in unique message handling
610-
$.severity.enable (Severity::information);
611-
$.maxConfigs = 2);
612-
Suppressions supprs;
613-
ErrorLogger2 errorLogger;
614-
CppCheck cppcheck(s, supprs, errorLogger, false, {});
615-
ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(test_file_a.path(), Path::identify(test_file_a.path(), false), 0)));
616-
// TODO: how to properly disable these warnings?
617-
errorLogger.errmsgs.erase(std::remove_if(errorLogger.errmsgs.begin(), errorLogger.errmsgs.end(), [](const ErrorMessage& msg) {
618-
return msg.id == "logChecker";
619-
}), errorLogger.errmsgs.end());
620-
// the internal errorlist is cleared after each check() call
621-
ASSERT_EQUALS(1, errorLogger.errmsgs.size());
622-
const auto it = errorLogger.errmsgs.cbegin();
623-
ASSERT_EQUALS("a.c:0:0: information: Too many #ifdef configurations - cppcheck only checks 2 of 4 configurations. Use --force to check all configurations. [toomanyconfigs]", it->toString(false, templateFormat, ""));
624-
}
625-
626596
void purgedConfiguration() const
627597
{
628598
ScopedFile test_file("test.cpp",

0 commit comments

Comments
 (0)