Fix #10039 (integrate `--check-config` include findings with normal analysis) / also fixes #11283 (#3229)

This commit is contained in:
Oliver Stöneberg 2023-03-04 09:02:35 +01:00 committed by GitHub
parent 50eb0641b9
commit 7fd4118d60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 124 additions and 227 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -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 ..

View File

@ -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);

View File

@ -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>

View File

@ -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.
- 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

View File

@ -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)

View File

@ -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)

View File

@ -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 = "";
}
}

View File

@ -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);

View File

@ -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());
}
};