Fix #10039 (integrate `--check-config` include findings with normal analysis) / also fixes #11283 (#3229)
This commit is contained in:
parent
50eb0641b9
commit
7fd4118d60
|
@ -449,12 +449,6 @@ jobs:
|
|||
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings"
|
||||
ec=0
|
||||
|
||||
# work around missingInclude not being reported with -j and the --check-config requirement for detailed warnings
|
||||
./cppcheck $selfcheck_options -DCHECK_INTERNAL cli lib --check-config --suppress=missingIncludeSystem --suppress=unmatchedSuppression || ec=1
|
||||
./cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 --library=qt --addon=naming.json -Igui/temp -Igui gui/*.cpp gui/temp/*.cpp --check-config --suppress=missingIncludeSystem --suppress=unmatchedSuppression || ec=1
|
||||
./cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp --check-config --suppress=missingIncludeSystem --suppress=unmatchedSuppression || ec=1
|
||||
./cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp --check-config --suppress=missingIncludeSystem --suppress=unmatchedSuppression || ec=1
|
||||
|
||||
# early exit
|
||||
if [ $ec -eq 1 ]; then
|
||||
exit $ec
|
||||
|
|
|
@ -13,6 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.15.2
|
||||
ASAN_OPTIONS: detect_stack_use_after_return=1
|
||||
|
||||
steps:
|
||||
|
@ -35,9 +36,16 @@ jobs:
|
|||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 16
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
cache: true
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On
|
||||
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On
|
||||
env:
|
||||
CC: clang-16
|
||||
CXX: clang++-16
|
||||
|
@ -53,6 +61,12 @@ jobs:
|
|||
- name: Run tests
|
||||
run: ./cmake.output/bin/testrunner
|
||||
|
||||
- name: Generate dependencies
|
||||
run: |
|
||||
# make sure auto-generated GUI files exist
|
||||
make -C cmake.output autogen
|
||||
make -C cmake.output gui-build-deps triage-build-ui-deps
|
||||
|
||||
# TODO: this is currently way too slow (~60 minutes) to enable it
|
||||
# TODO: only fail the step on sanitizer issues
|
||||
- name: Self check
|
||||
|
@ -61,7 +75,7 @@ jobs:
|
|||
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings"
|
||||
ec=0
|
||||
./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 --library=qt --addon=naming.json -Igui/temp -Igui gui/*.cpp gui/temp/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
|
||||
exit $ec
|
||||
|
|
|
@ -13,6 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.15.2
|
||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1:report_error_type=1
|
||||
|
||||
steps:
|
||||
|
@ -35,9 +36,16 @@ jobs:
|
|||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 16
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
cache: true
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On
|
||||
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On
|
||||
env:
|
||||
CC: clang-16
|
||||
CXX: clang++-16
|
||||
|
@ -53,13 +61,19 @@ jobs:
|
|||
- name: Run tests
|
||||
run: ./cmake.output/bin/testrunner
|
||||
|
||||
- name: Generate dependencies
|
||||
run: |
|
||||
# make sure auto-generated GUI files exist
|
||||
make -C cmake.output autogen
|
||||
make -C cmake.output gui-build-deps triage-build-ui-deps
|
||||
|
||||
# TODO: only fail the step on sanitizer issues
|
||||
- name: Self check
|
||||
run: |
|
||||
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings"
|
||||
ec=0
|
||||
./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 --library=qt --addon=naming.json -Igui/temp -Igui gui/*.cpp gui/temp/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
|
||||
exit $ec
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
missingIncludeSystem
|
||||
shadowFunction
|
||||
bitwiseOnBoolean
|
||||
|
||||
|
@ -11,7 +12,9 @@ simplifyUsing:gui/temp/moc_*.cpp
|
|||
funcArgNamesDifferent:gui/temp/moc_*.cpp
|
||||
symbolDatabaseWarning:tools/triage/temp/moc_*.cpp
|
||||
naming-varname:gui/temp/ui_*.h
|
||||
naming-varname:cmake.output/gui/ui_*.h
|
||||
functionStatic:gui/temp/ui_fileview.h
|
||||
functionStatic:cmake.output/gui/ui_fileview.h
|
||||
|
||||
# --debug-warnings suppressions
|
||||
valueFlowBailout
|
||||
|
|
|
@ -1136,8 +1136,7 @@ void CmdLineParser::printHelp()
|
|||
" to only enable this when the whole program is\n"
|
||||
" scanned.\n"
|
||||
" * missingInclude\n"
|
||||
" Warn if there are missing includes. For\n"
|
||||
" detailed information, use '--check-config'.\n"
|
||||
" Warn if there are missing includes.\n"
|
||||
" Several ids can be given if you separate them with\n"
|
||||
" commas. See also --std\n"
|
||||
" --error-exitcode=<n> If errors are found, integer [n] is returned instead of\n"
|
||||
|
|
|
@ -198,9 +198,6 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
|||
|
||||
int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||
{
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
CheckUnusedFunctions::clear();
|
||||
|
||||
CppCheck cppCheck(*this, true, executeCommand);
|
||||
|
@ -380,29 +377,6 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
|
|||
|
||||
if (!settings.checkConfiguration) {
|
||||
cppcheck.tooManyConfigsError(emptyString,0U);
|
||||
|
||||
if (settings.checks.isEnabled(Checks::missingInclude) && (Preprocessor::missingIncludeFlag || Preprocessor::missingSystemIncludeFlag)) {
|
||||
const std::list<ErrorMessage::FileLocation> callStack;
|
||||
ErrorMessage msg(callStack,
|
||||
emptyString,
|
||||
Severity::information,
|
||||
"Cppcheck cannot find all the include files (use --check-config for details)\n"
|
||||
"Cppcheck cannot find all the include files. Cppcheck can check the code without the "
|
||||
"include files found. But the results will probably be more accurate if all the include "
|
||||
"files are found. Please check your project's include directories and add all of them "
|
||||
"as include directories for Cppcheck. To see what files Cppcheck cannot find use "
|
||||
"--check-config.",
|
||||
"",
|
||||
Certainty::normal);
|
||||
if (Preprocessor::missingIncludeFlag) {
|
||||
msg.id = "missingInclude";
|
||||
reportInfo(msg);
|
||||
}
|
||||
if (Preprocessor::missingSystemIncludeFlag) {
|
||||
msg.id = "missingIncludeSystem";
|
||||
reportInfo(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.xml) {
|
||||
|
|
|
@ -62,9 +62,6 @@ Directive::Directive(std::string _file, const int _linenr, const std::string &_s
|
|||
str(trim(_str))
|
||||
{}
|
||||
|
||||
std::atomic<bool> Preprocessor::missingIncludeFlag;
|
||||
std::atomic<bool> Preprocessor::missingSystemIncludeFlag;
|
||||
|
||||
char Preprocessor::macroChar = char(1);
|
||||
|
||||
Preprocessor::Preprocessor(Settings& settings, ErrorLogger *errorLogger) : mSettings(settings), mErrorLogger(errorLogger)
|
||||
|
@ -836,27 +833,19 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const
|
|||
// Report that include is missing
|
||||
void Preprocessor::missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, HeaderTypes headerType)
|
||||
{
|
||||
if (!mSettings.checks.isEnabled(Checks::missingInclude) && !mSettings.checkConfiguration)
|
||||
if (!mSettings.checks.isEnabled(Checks::missingInclude))
|
||||
return;
|
||||
|
||||
std::string fname = Path::fromNativeSeparators(filename);
|
||||
std::string errorId = (headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude";
|
||||
Suppressions::ErrorMessage errorMessage;
|
||||
errorMessage.errorId = "missingInclude";
|
||||
errorMessage.errorId = errorId;
|
||||
errorMessage.setFileName(std::move(fname));
|
||||
errorMessage.lineNumber = linenr;
|
||||
if (mSettings.nomsg.isSuppressed(errorMessage))
|
||||
return;
|
||||
errorMessage.errorId = "missingIncludeSystem";
|
||||
if (headerType == SystemHeader && mSettings.nomsg.isSuppressed(errorMessage))
|
||||
return;
|
||||
|
||||
if (headerType == SystemHeader)
|
||||
missingSystemIncludeFlag = true;
|
||||
else
|
||||
missingIncludeFlag = true;
|
||||
|
||||
if (mErrorLogger && mSettings.checkConfiguration) {
|
||||
|
||||
if (mErrorLogger) {
|
||||
std::list<ErrorMessage::FileLocation> locationList;
|
||||
if (!filename.empty()) {
|
||||
ErrorMessage::FileLocation loc;
|
||||
|
@ -864,13 +853,13 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line
|
|||
loc.setfile(Path::toNativeSeparators(filename));
|
||||
locationList.push_back(std::move(loc));
|
||||
}
|
||||
ErrorMessage errmsg(locationList, mFile0, Severity::information,
|
||||
ErrorMessage errmsg(std::move(locationList), mFile0, Severity::information,
|
||||
(headerType==SystemHeader) ?
|
||||
"Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results." :
|
||||
"Include file: \"" + header + "\" not found.",
|
||||
(headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude",
|
||||
std::move(errorId),
|
||||
Certainty::normal);
|
||||
mErrorLogger->reportInfo(errmsg);
|
||||
mErrorLogger->reportErr(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,7 +867,6 @@ void Preprocessor::getErrorMessages(ErrorLogger *errorLogger, const Settings *se
|
|||
{
|
||||
Settings settings2(*settings);
|
||||
Preprocessor preprocessor(settings2, errorLogger);
|
||||
settings2.checkConfiguration = true;
|
||||
preprocessor.missingInclude(emptyString, 1, emptyString, UserHeader);
|
||||
preprocessor.missingInclude(emptyString, 1, emptyString, SystemHeader);
|
||||
preprocessor.error(emptyString, 1, "#error message"); // #error ..
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <istream>
|
||||
#include <list>
|
||||
|
@ -87,9 +86,6 @@ public:
|
|||
explicit Preprocessor(Settings& settings, ErrorLogger *errorLogger = nullptr);
|
||||
virtual ~Preprocessor();
|
||||
|
||||
static std::atomic<bool> missingIncludeFlag;
|
||||
static std::atomic<bool> missingSystemIncludeFlag;
|
||||
|
||||
void inlineSuppressions(const simplecpp::TokenList &tokens);
|
||||
|
||||
void setDirectives(const simplecpp::TokenList &tokens);
|
||||
|
|
|
@ -295,7 +295,7 @@ Example: '-UDEBUG'</para>
|
|||
enables unusedFunction.</para></glossdef></glossentry><glossentry><glossterm>warning</glossterm><glossdef><para>Enable warning messages</para></glossdef></glossentry><glossentry><glossterm>style</glossterm><glossdef><para>Enable all coding style checks. All messages with the
|
||||
severities 'style', 'performance' and 'portability' are
|
||||
enabled.</para></glossdef></glossentry><glossentry><glossterm>performance</glossterm><glossdef><para>Enable performance messages</para></glossdef></glossentry><glossentry><glossterm>portability</glossterm><glossdef><para>Enable portability messages</para></glossdef></glossentry><glossentry><glossterm>information</glossterm><glossdef><para>Enable information messages</para></glossdef></glossentry><glossentry><glossterm>unusedFunction</glossterm><glossdef><para>Check for unused functions. It is recommend to only
|
||||
enable this when the whole program is scanned</para></glossdef></glossentry><glossentry><glossterm>missingInclude</glossterm><glossdef><para>Warn if there are missing includes. For detailed information use --check-config</para></glossdef></glossentry></glosslist>
|
||||
enable this when the whole program is scanned</para></glossdef></glossentry><glossentry><glossterm>missingInclude</glossterm><glossdef><para>Warn if there are missing includes</para></glossdef></glossentry></glosslist>
|
||||
By default none of the additional checks are enabled. Several ids can be given if you separate them with commas, e.g. --enable=style,unusedFunction. See also --std
|
||||
</para>
|
||||
</listitem>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
release notes for cppcheck-2.11
|
||||
|
||||
- The platform type 'Unspecified' within .cppcheck projects has been deprecated and will be removed in Cppcheck 2.14. Please use 'unspecified' instead.
|
||||
- It is no longer necessary to run "--check-config" to get detailed "missingInclude" and "missingIncludeSystem" messages. They will always be issued in the regular analysis if "missingInclude" is enabled.
|
||||
- "missingInclude" and "missingIncludeSystem" are reported with "-j" is > 1 and processes are used in the backend (default in non-Windows binaries)
|
||||
- "missingInclude" and "missingIncludeSystem" will now cause the "--error-exitcode" to be applied
|
|
@ -198,16 +198,15 @@ def test_build_dir_dump_output():
|
|||
assert '</dump>' in dump, 'invalid dump data: ...' + dump[-100:]
|
||||
|
||||
def __test_missing_include_system(use_j):
|
||||
args = '--enable=missingInclude --suppress=zerodiv helloworld'
|
||||
args = ['--enable=missingInclude', '--suppress=zerodiv', '--template={file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]', 'helloworld']
|
||||
if use_j:
|
||||
args = '-j2 ' + args
|
||||
args.insert(0, '-j2')
|
||||
|
||||
_, _, stderr = cppcheck(args.split())
|
||||
assert stderr == 'nofile:0:0: information: Cppcheck cannot find all the include files (use --check-config for details) [missingIncludeSystem]\n\n'
|
||||
_, _, stderr = cppcheck(args)
|
||||
assert stderr.replace('\\', '/') == 'helloworld/main.c:1:0: information: Include file: <stdio.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n'
|
||||
|
||||
def test_missing_include_system():
|
||||
__test_missing_include_system(False)
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_missing_include_system_j(): #11283
|
||||
__test_missing_include_system(True)
|
||||
|
|
|
@ -13,17 +13,16 @@ def __test_missing_include(tmpdir, use_j):
|
|||
#include "test.h"
|
||||
""")
|
||||
|
||||
args = '--enable=missingInclude {}'.format(test_file)
|
||||
args = ['--enable=missingInclude', '--template={file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]', test_file]
|
||||
if use_j:
|
||||
args = '-j2 ' + args
|
||||
args.insert(0, '-j2')
|
||||
|
||||
_, _, stderr = cppcheck(args.split())
|
||||
assert stderr == 'nofile:0:0: information: Cppcheck cannot find all the include files (use --check-config for details) [missingInclude]\n\n'
|
||||
_, _, stderr = cppcheck(args)
|
||||
assert stderr == '{}:2:0: information: Include file: "test.h" not found. [missingInclude]\n'.format(test_file)
|
||||
|
||||
def test_missing_include(tmpdir):
|
||||
__test_missing_include(tmpdir, False)
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_missing_include_j(tmpdir): #11283
|
||||
__test_missing_include(tmpdir, True)
|
||||
|
||||
|
@ -40,7 +39,7 @@ def __test_missing_include_check_config(tmpdir, use_j):
|
|||
args = '-j2 ' + args
|
||||
|
||||
_, _, stderr = cppcheck(args.split())
|
||||
assert stderr == '{}:2:0: information: Include file: "test.h" not found. [missingInclude]\n\n^\n'.format(test_file)
|
||||
assert stderr == '' # --check-config no longer reports the missing includes
|
||||
|
||||
def test_missing_include_check_config(tmpdir):
|
||||
__test_missing_include_check_config(tmpdir, False)
|
||||
|
|
|
@ -394,3 +394,19 @@ void TestFixture::reportErr(const ErrorMessage &msg)
|
|||
if (errout.str().find(errormessage) == std::string::npos)
|
||||
errout << errormessage << std::endl;
|
||||
}
|
||||
|
||||
void TestFixture::setTemplateFormat(const std::string &templateFormat)
|
||||
{
|
||||
if (templateFormat == "multiline") {
|
||||
mTemplateFormat = "{file}:{line}:{severity}:{message}";
|
||||
mTemplateLocation = "{file}:{line}:note:{info}";
|
||||
}
|
||||
else if (templateFormat == "simple") {
|
||||
mTemplateFormat = "{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]";
|
||||
mTemplateLocation = "";
|
||||
}
|
||||
else {
|
||||
mTemplateFormat = templateFormat;
|
||||
mTemplateLocation = "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,9 +102,10 @@ protected:
|
|||
mVerbose = v;
|
||||
}
|
||||
|
||||
void setTemplateFormat(const std::string &templateFormat);
|
||||
|
||||
void setMultiline() {
|
||||
mTemplateFormat = "{file}:{line}:{severity}:{message}";
|
||||
mTemplateLocation = "{file}:{line}:note:{info}";
|
||||
setTemplateFormat("multiline");
|
||||
}
|
||||
|
||||
void processOptions(const options& args);
|
||||
|
|
|
@ -204,7 +204,6 @@ private:
|
|||
|
||||
// inline suppression, missingInclude/missingIncludeSystem
|
||||
TEST_CASE(inline_suppression_for_missing_include);
|
||||
TEST_CASE(inline_suppression_for_missing_include_check_config);
|
||||
|
||||
// Using -D to predefine symbols
|
||||
TEST_CASE(predefine1);
|
||||
|
@ -1946,16 +1945,11 @@ private:
|
|||
preprocess("#define () {(int f(x) }\n", actual); // don't hang
|
||||
}
|
||||
|
||||
void inline_suppression_for_missing_include_internal(bool checkConfig) {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
void inline_suppression_for_missing_include() {
|
||||
Settings settings;
|
||||
settings.checkConfiguration = checkConfig;
|
||||
settings.inlineSuppressions = true;
|
||||
settings.severity.clear();
|
||||
// --check-config needs to report this regardless of the emanled checks
|
||||
if (!checkConfig)
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
const std::string code("// cppcheck-suppress missingInclude\n"
|
||||
|
@ -1966,8 +1960,6 @@ private:
|
|||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
auto suppressions = settings.nomsg.getSuppressions();
|
||||
ASSERT_EQUALS(2, suppressions.size());
|
||||
|
@ -1989,14 +1981,6 @@ private:
|
|||
ASSERT_EQUALS(true, suppr.matched);
|
||||
}
|
||||
|
||||
void inline_suppression_for_missing_include() {
|
||||
inline_suppression_for_missing_include_internal(false);
|
||||
}
|
||||
|
||||
void inline_suppression_for_missing_include_check_config() {
|
||||
inline_suppression_for_missing_include_internal(true);
|
||||
}
|
||||
|
||||
void predefine1() {
|
||||
const std::string src("#if defined X || Y\n"
|
||||
"Fred & Wilma\n"
|
||||
|
@ -2412,13 +2396,12 @@ private:
|
|||
|
||||
// test for existing local include
|
||||
void testMissingInclude() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "");
|
||||
|
@ -2426,49 +2409,35 @@ private:
|
|||
std::string code("#include \"header.h\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
}
|
||||
|
||||
// test for missing local include
|
||||
void testMissingInclude2() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
std::string code("#include \"header.h\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: \"header.h\" not found. [missingInclude]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for missing local include - no include path given
|
||||
void testMissingInclude3() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "", "inc");
|
||||
|
@ -2476,26 +2445,19 @@ private:
|
|||
std::string code("#include \"header.h\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: \"header.h\" not found. [missingInclude]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for existing local include - include path provided
|
||||
void testMissingInclude4() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.includePaths.emplace_back("inc");
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "", "inc");
|
||||
|
@ -2503,26 +2465,19 @@ private:
|
|||
std::string code("#include \"inc/header.h\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
}
|
||||
|
||||
// test for existing local include - absolute path
|
||||
void testMissingInclude5() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.includePaths.emplace_back("inc");
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "", Path::getCurrentPath());
|
||||
|
@ -2530,25 +2485,18 @@ private:
|
|||
std::string code("#include \"" + header.path() + "\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
}
|
||||
|
||||
// test for missing local include - absolute path
|
||||
void testMissingInclude6() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
const std::string header = Path::join(Path::getCurrentPath(), "header.h");
|
||||
|
@ -2556,25 +2504,18 @@ private:
|
|||
std::string code("#include \"" + header + "\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: \"" + header + "\" not found. [missingInclude]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for missing system include - system includes are not searched for in relative path
|
||||
void testMissingSystemInclude() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "");
|
||||
|
@ -2582,50 +2523,37 @@ private:
|
|||
std::string code("#include <header.h>");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: <header.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for missing system include
|
||||
void testMissingSystemInclude2() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
std::string code("#include <header.h>");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: <header.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for existing system include in system include path
|
||||
void testMissingSystemInclude3() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
settings.includePaths.emplace_back("system");
|
||||
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "", "system");
|
||||
|
@ -2633,26 +2561,19 @@ private:
|
|||
std::string code("#include <header.h>");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
}
|
||||
|
||||
// test for existing system include - absolute path
|
||||
void testMissingSystemInclude4() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.includePaths.emplace_back("inc");
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "", Path::getCurrentPath());
|
||||
|
@ -2660,25 +2581,18 @@ private:
|
|||
std::string code("#include <" + header.path() + ">");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
}
|
||||
|
||||
// test for missing system include - absolute path
|
||||
void testMissingSystemInclude5() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
const std::string header = Path::join(Path::getCurrentPath(), "header.h");
|
||||
|
@ -2686,25 +2600,18 @@ private:
|
|||
std::string code("#include <" + header + ">");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout.str());
|
||||
}
|
||||
|
||||
// test for missing local and system include
|
||||
void testMissingIncludeMixed() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "");
|
||||
|
@ -2716,26 +2623,21 @@ private:
|
|||
"#include \"header2.h\"");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
// the expected messages are emitted outside of the Preprocessor
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: \"missing.h\" not found. [missingInclude]\n"
|
||||
"test.c:2:0: information: Include file: <header.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n"
|
||||
"test.c:3:0: information: Include file: <missing2.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout.str());
|
||||
}
|
||||
|
||||
void testMissingIncludeCheckConfig() {
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
|
||||
Settings settings;
|
||||
settings.clearIncludeCache = true;
|
||||
settings.checkConfiguration = true;
|
||||
settings.severity.clear();
|
||||
settings.checks.enable(Checks::missingInclude);
|
||||
settings.includePaths.emplace_back("system");
|
||||
// needs to be reported regardless of enabled checks
|
||||
settings.templateFormat = "simple"; // has no effect
|
||||
setTemplateFormat("simple");
|
||||
|
||||
Preprocessor preprocessor(settings, this);
|
||||
|
||||
ScopedFile header("header.h", "");
|
||||
|
@ -2761,18 +2663,13 @@ private:
|
|||
"#include <" + missing4 + ">\n");
|
||||
errout.str("");
|
||||
preprocessor.getcode(code, "", "test.c");
|
||||
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
|
||||
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
|
||||
|
||||
ASSERT_EQUALS("[test.c:1]: (information) Include file: \"missing.h\" not found.\n"
|
||||
"[test.c:2]: (information) Include file: <header.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.\n"
|
||||
"[test.c:3]: (information) Include file: <missing2.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.\n"
|
||||
"[test.c:6]: (information) Include file: \"header4.h\" not found.\n"
|
||||
"[test.c:9]: (information) Include file: \"" + missing3 + "\" not found.\n"
|
||||
"[test.c:11]: (information) Include file: <" + missing4 + "> not found. Please note: Cppcheck does not need standard library headers to get proper results.\n", errout.str());
|
||||
|
||||
Preprocessor::missingIncludeFlag = false;
|
||||
Preprocessor::missingSystemIncludeFlag = false;
|
||||
ASSERT_EQUALS("test.c:1:0: information: Include file: \"missing.h\" not found. [missingInclude]\n"
|
||||
"test.c:2:0: information: Include file: <header.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n"
|
||||
"test.c:3:0: information: Include file: <missing2.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n"
|
||||
"test.c:6:0: information: Include file: \"header4.h\" not found. [missingInclude]\n"
|
||||
"test.c:9:0: information: Include file: \"" + missing3 + "\" not found. [missingInclude]\n"
|
||||
"test.c:11:0: information: Include file: <" + missing4 + "> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue