From cbce58e5c69a5e8be0ff811c2e2018ed974511ec Mon Sep 17 00:00:00 2001
From: firewave <firewave@users.noreply.github.com>
Date: Thu, 13 Jun 2024 01:48:27 +0200
Subject: [PATCH] store language in `FileWithDetails`

---
 cli/cmdlineparser.cpp         | 68 ++++++++++++++++++++++++++++
 cli/filelister.cpp            | 12 ++---
 gui/checkthread.cpp           |  2 +-
 lib/filesettings.h            | 21 +++++++--
 lib/path.cpp                  |  7 ++-
 lib/path.h                    | 10 +++--
 test/cli/clang-import_test.py | 19 +++++++-
 test/testcmdlineparser.cpp    |  9 ++++
 test/testfilelister.cpp       | 83 ++++++++++++++++++++++++++++++++---
 test/testfilesettings.cpp     |  8 +++-
 test/testpath.cpp             | 25 +++++++++++
 test/testprocessexecutor.cpp  |  8 ++--
 test/testsingleexecutor.cpp   |  9 ++--
 test/testsuppressions.cpp     | 12 ++---
 test/testthreadexecutor.cpp   |  8 ++--
 15 files changed, 258 insertions(+), 43 deletions(-)

diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
index 8964cfcd1a6..0bc0052f576 100644
--- a/cli/cmdlineparser.cpp
+++ b/cli/cmdlineparser.cpp
@@ -214,6 +214,39 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
 
         mFileSettings.clear();
 
+        if (mSettings.enforcedLang != Standards::Language::None)
+        {
+            // apply enforced language
+            for (auto& fs : fileSettings)
+            {
+                if (mSettings.library.markupFile(fs.filename()))
+                    continue;
+                fs.file.setLang(mSettings.enforcedLang);
+            }
+        }
+        else
+        {
+            // identify files
+            for (auto& fs : fileSettings)
+            {
+                if (mSettings.library.markupFile(fs.filename()))
+                    continue;
+                bool header = false;
+                fs.file.setLang(Path::identify(fs.filename(), mSettings.cppHeaderProbe, &header));
+                // unknown extensions default to C++
+                if (!header && fs.file.lang() == Standards::Language::None)
+                    fs.file.setLang(Standards::Language::CPP);
+            }
+        }
+
+        // enforce the language since markup files are special and do not adhere to the enforced language
+        for (auto& fs : fileSettings)
+        {
+            if (mSettings.library.markupFile(fs.filename())) {
+                fs.file.setLang(Standards::Language::C);
+            }
+        }
+
         // sort the markup last
         std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) {
             return !mSettings.library.markupFile(fs.filename()) || !mSettings.library.processMarkupAfterCode(fs.filename());
@@ -284,6 +317,41 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
             files = std::move(filesResolved);
         }
 
+        if (mSettings.enforcedLang != Standards::Language::None)
+        {
+            // apply enforced language
+            for (auto& f : files)
+            {
+                if (mSettings.library.markupFile(f.path()))
+                    continue;
+                f.setLang(mSettings.enforcedLang);
+            }
+        }
+        else
+        {
+            // identify remaining files
+            for (auto& f : files)
+            {
+                if (f.lang() != Standards::Language::None)
+                    continue;
+                if (mSettings.library.markupFile(f.path()))
+                    continue;
+                bool header = false;
+                f.setLang(Path::identify(f.path(), mSettings.cppHeaderProbe, &header));
+                // unknown extensions default to C++
+                if (!header && f.lang() == Standards::Language::None)
+                    f.setLang(Standards::Language::CPP);
+            }
+        }
+
+        // enforce the language since markup files are special and do not adhere to the enforced language
+        for (auto& f : files)
+        {
+            if (mSettings.library.markupFile(f.path())) {
+                f.setLang(Standards::Language::C);
+            }
+        }
+
         // sort the markup last
         std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const FileWithDetails& entry) {
             return !mSettings.library.markupFile(entry.path()) || !mSettings.library.processMarkupAfterCode(entry.path());
diff --git a/cli/filelister.cpp b/cli/filelister.cpp
index 0ca51d8bff7..841f84ae89e 100644
--- a/cli/filelister.cpp
+++ b/cli/filelister.cpp
@@ -104,7 +104,8 @@ static std::string addFiles2(std::list<FileWithDetails>&files, const std::string
 
             if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
                 // File
-                if ((!checkAllFilesInDir || Path::acceptFile(fname, extra)) && !ignored.match(fname)) {
+                Standards::Language lang = Standards::Language::None;
+                if ((!checkAllFilesInDir || Path::acceptFile(fname, extra, &lang)) && !ignored.match(fname)) {
                     std::string nativename = Path::fromNativeSeparators(fname);
 
                     // Limitation: file sizes are assumed to fit in a 'size_t'
@@ -114,7 +115,7 @@ static std::string addFiles2(std::list<FileWithDetails>&files, const std::string
                     const std::size_t filesize = ffd.nFileSizeLow;
 
 #endif
-                    files.emplace_back(std::move(nativename), filesize);
+                    files.emplace_back(std::move(nativename), lang, filesize);
                 }
             } else {
                 // Directory
@@ -192,7 +193,7 @@ static std::string addFiles2(std::list<FileWithDetails> &files,
         return ""; // TODO: return error?
     if ((file_stat.st_mode & S_IFMT) != S_IFDIR)
     {
-        files.emplace_back(path, file_stat.st_size);
+        files.emplace_back(path, Standards::Language::None, file_stat.st_size);
         return "";
     }
 
@@ -229,12 +230,13 @@ static std::string addFiles2(std::list<FileWithDetails> &files,
                 }
             }
         } else {
-            if (Path::acceptFile(new_path, extra) && !ignored.match(new_path)) {
+            Standards::Language lang = Standards::Language::None;
+            if (Path::acceptFile(new_path, extra, &lang) && !ignored.match(new_path)) {
                 if (stat(new_path.c_str(), &file_stat) == -1) {
                     const int err = errno;
                     return "could not stat file '" + new_path + "' (errno: " + std::to_string(err) + ")";
                 }
-                files.emplace_back(new_path, file_stat.st_size);
+                files.emplace_back(new_path, lang, file_stat.st_size);
             }
         }
     }
diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp
index 09161fbe752..cd483beaa9a 100644
--- a/gui/checkthread.cpp
+++ b/gui/checkthread.cpp
@@ -139,7 +139,7 @@ void CheckThread::run()
         qDebug() << "Whole program analysis";
         std::list<FileWithDetails> files2;
         std::transform(mFiles.cbegin(), mFiles.cend(), std::back_inserter(files2), [&](const QString& file) {
-            return FileWithDetails{file.toStdString(), 0};
+            return FileWithDetails{file.toStdString(), Path::identify(file.toStdString(), cppcheck.settings().cppHeaderProbe), 0};
         });
         cppcheck.analyseWholeProgram(cppcheck.settings().buildDir, files2, {}, ctuInfo);
         mFiles.clear();
diff --git a/lib/filesettings.h b/lib/filesettings.h
index 75bf8faaa50..5b3039cd4e7 100644
--- a/lib/filesettings.h
+++ b/lib/filesettings.h
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "path.h"
 #include "platform.h"
+#include "standards.h"
 
 #include <list>
 #include <set>
@@ -33,12 +34,13 @@ class FileWithDetails
 {
 public:
     explicit FileWithDetails(std::string path)
-        : FileWithDetails(std::move(path), 0)
+        : FileWithDetails(std::move(path), Standards::Language::None, 0)
     {}
 
-    FileWithDetails(std::string path, std::size_t size)
+    FileWithDetails(std::string path, Standards::Language lang, std::size_t size)
         : mPath(std::move(path))
         , mPathSimplified(Path::simplifyPath(mPath))
+        , mLang(lang)
         , mSize(size)
     {
         if (mPath.empty())
@@ -59,9 +61,20 @@ class FileWithDetails
     {
         return mSize;
     }
+
+    void setLang(Standards::Language lang)
+    {
+        mLang = lang;
+    }
+
+    Standards::Language lang() const
+    {
+        return mLang;
+    }
 private:
     std::string mPath;
     std::string mPathSimplified;
+    Standards::Language mLang = Standards::Language::None;
     std::size_t mSize;
 };
 
@@ -71,8 +84,8 @@ struct CPPCHECKLIB FileSettings {
         : file(std::move(path))
     {}
 
-    FileSettings(std::string path, std::size_t size)
-        : file(std::move(path), size)
+    FileSettings(std::string path, Standards::Language lang, std::size_t size)
+        : file(std::move(path), lang, size)
     {}
 
     std::string cfg;
diff --git a/lib/path.cpp b/lib/path.cpp
index a932c15d448..3a1d517db36 100644
--- a/lib/path.cpp
+++ b/lib/path.cpp
@@ -216,10 +216,13 @@ static const std::unordered_set<std::string> header_exts = {
     ".h", ".hpp", ".h++", ".hxx", ".hh"
 };
 
-bool Path::acceptFile(const std::string &path, const std::set<std::string> &extra)
+bool Path::acceptFile(const std::string &path, const std::set<std::string> &extra, Standards::Language* lang)
 {
     bool header = false;
-    return (identify(path, false, &header) != Standards::Language::None && !header) || extra.find(getFilenameExtension(path)) != extra.end();
+    Standards::Language l = identify(path, false, &header);
+    if (lang)
+        *lang = l;
+    return (l != Standards::Language::None && !header) || extra.find(getFilenameExtension(path)) != extra.end();
 }
 
 static bool hasEmacsCppMarker(const char* path)
diff --git a/lib/path.h b/lib/path.h
index fda36c01f85..db22773ed65 100644
--- a/lib/path.h
+++ b/lib/path.h
@@ -137,21 +137,23 @@ class CPPCHECKLIB Path {
      * @brief Check if the file extension indicates that it's a C/C++ source file.
      * Check if the file has source file extension: *.c;*.cpp;*.cxx;*.c++;*.cc;*.txx
      * @param filename filename to check. path info is optional
+     * @param lang the detected language
      * @return true if the file extension indicates it should be checked
      */
-    static bool acceptFile(const std::string &filename) {
+    static bool acceptFile(const std::string &filename, Standards::Language* lang = nullptr) {
         const std::set<std::string> extra;
-        return acceptFile(filename, extra);
+        return acceptFile(filename, extra, lang);
     }
 
     /**
      * @brief Check if the file extension indicates that it's a C/C++ source file.
      * Check if the file has source file extension: *.c;*.cpp;*.cxx;*.c++;*.cc;*.txx
      * @param path filename to check. path info is optional
-     * @param extra    extra file extensions
+     * @param extra extra file extensions
+     * @param lang the detected language
      * @return true if the file extension indicates it should be checked
      */
-    static bool acceptFile(const std::string &path, const std::set<std::string> &extra);
+    static bool acceptFile(const std::string &path, const std::set<std::string> &extra, Standards::Language* lang = nullptr);
 
     /**
      * @brief Is filename a header based on file extension
diff --git a/test/cli/clang-import_test.py b/test/cli/clang-import_test.py
index af1acf5cd5f..4e0b7e09e48 100644
--- a/test/cli/clang-import_test.py
+++ b/test/cli/clang-import_test.py
@@ -139,10 +139,10 @@ def test_warning(tmpdir):  # #12424
     assert stderr == ''
 
 
-def __test_cmd(tmp_path, file_name, extra_args, stdout_exp_1):
+def __test_cmd(tmp_path, file_name, extra_args, stdout_exp_1, content=''):
     test_file = tmp_path / file_name
     with open(test_file, 'wt') as f:
-        f.write('')
+        f.write(content)
 
     args = [
         '--enable=information',
@@ -173,6 +173,21 @@ def test_cmd_cpp(tmp_path):
     __test_cmd(tmp_path, 'test.cpp', [], '-x c++')
 
 
+# files with unknown extensions are treated as C++
+@pytest.mark.xfail(strict=True)
+def test_cmd_unk(tmp_path):
+    __test_cmd(tmp_path, 'test.cplusplus', [], '-x c++')
+
+
+# headers are treated as C by default
+def test_cmd_hdr(tmp_path):
+    __test_cmd(tmp_path, 'test.h', [], '-x c')
+
+
+def test_cmd_hdr_probe(tmp_path):
+    __test_cmd(tmp_path, 'test.h', ['--cpp-header-probe'], '-x c++', '// -*- C++ -*-')
+
+
 def test_cmd_inc(tmp_path):
     inc_path = tmp_path / 'inc'
     os.makedirs(inc_path)
diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp
index 8684bf973b8..3ef8a4423a5 100644
--- a/test/testcmdlineparser.cpp
+++ b/test/testcmdlineparser.cpp
@@ -430,6 +430,8 @@ class TestCmdlineParser : public TestFixture {
         TEST_CASE(ignorefilepaths2);
         TEST_CASE(ignorefilepaths3);
 
+        TEST_CASE(nonexistentpath);
+
         TEST_CASE(checkconfig);
         TEST_CASE(unknownParam);
 
@@ -2955,6 +2957,13 @@ class TestCmdlineParser : public TestFixture {
         ASSERT_EQUALS("foo.cpp", parser->getIgnoredPaths()[0]);
     }
 
+    void nonexistentpath() {
+        REDIRECT;
+        const char * const argv[] = {"cppcheck", "file.cpp"};
+        ASSERT(!parser->fillSettingsFromArgs(2, argv));
+        ASSERT_EQUALS("cppcheck: error: could not find or open any of the paths given.\n", logger->str());
+    }
+
     void checkconfig() {
         REDIRECT;
         const char * const argv[] = {"cppcheck", "--check-config", "file.cpp"};
diff --git a/test/testfilelister.cpp b/test/testfilelister.cpp
index 092ac86a3b6..873055a782f 100644
--- a/test/testfilelister.cpp
+++ b/test/testfilelister.cpp
@@ -39,6 +39,7 @@ class TestFileLister : public TestFixture {
         TEST_CASE(recursiveAddFilesEmptyPath);
         TEST_CASE(excludeFile1);
         TEST_CASE(excludeFile2);
+        TEST_CASE(addFiles);
     }
 
     // TODO: generate file list instead
@@ -81,11 +82,25 @@ class TestFileLister : public TestFixture {
         };
 
         // Make sure source files are added..
-        ASSERT(find_file(dirprefix + "cli/main.cpp") != files.end());
-        ASSERT(find_file(dirprefix + "lib/token.cpp") != files.end());
-        ASSERT(find_file(dirprefix + "lib/tokenize.cpp") != files.end());
-        ASSERT(find_file(dirprefix + "gui/main.cpp") != files.end());
-        ASSERT(find_file(dirprefix + "test/testfilelister.cpp") != files.end());
+        auto it = find_file(dirprefix + "cli/main.cpp");
+        ASSERT(it != files.end());
+        ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang());
+
+        it = find_file(dirprefix + "lib/token.cpp");
+        ASSERT(it != files.end());
+        ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang());
+
+        it = find_file(dirprefix + "lib/tokenize.cpp");
+        ASSERT(it != files.end());
+        ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang());
+
+        it = find_file(dirprefix + "gui/main.cpp");
+        ASSERT(it != files.end());
+        ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang());
+
+        it = find_file(dirprefix + "test/testfilelister.cpp");
+        ASSERT(it != files.end());
+        ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang());
 
         // Make sure headers are not added..
         ASSERT(find_file(dirprefix + "lib/tokenize.h") == files.end());
@@ -120,7 +135,65 @@ class TestFileLister : public TestFixture {
         ASSERT_EQUALS(basedir + "lib/token.cpp", files.begin()->path());
     }
 
+    void addFiles() const {
+        const std::string adddir = findBaseDir() + ".";
+
+        // TODO: on Windows the prefix is different from when a recursive a folder (see recursiveAddFiles test)
+        const std::string dirprefix = adddir + "/";
+#ifdef _WIN32
+        const std::string dirprefix_nat = Path::toNativeSeparators(dirprefix);
+#endif
+
+        std::list<FileWithDetails> files;
+
+        {
+            const std::string addfile = Path::join(Path::join(adddir, "cli"), "main.cpp");
+            const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch({}));
+            ASSERT_EQUALS("", err);
+        }
+        {
+            const std::string addfile = Path::join(Path::join(adddir, "lib"), "token.cpp");
+            const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch({}));
+            ASSERT_EQUALS("", err);
+        }
+        {
+            const std::string addfile = Path::join(Path::join(adddir, "cli"), "token.cpp"); // does not exist
+            const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch({}));
+            ASSERT_EQUALS("", err);
+        }
+        {
+            const std::string addfile = Path::join(Path::join(adddir, "lib2"), "token.cpp"); // does not exist
+            const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch({}));
+#ifdef _WIN32
+            // TODO: get rid of this error - caused by missing intermediate folder
+            ASSERT_EQUALS("finding files failed. Search pattern: '" + dirprefix_nat + "lib2\\token.cpp'. (error: 3)", err);
+#else
+            ASSERT_EQUALS("", err);
+#endif
+        }
+        {
+            const std::string addfile = Path::join(Path::join(adddir, "lib"), "matchcompiler.h");
+            const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch({}));
+            ASSERT_EQUALS("", err);
+        }
+
+        ASSERT_EQUALS(3, files.size());
+        auto it = files.cbegin();
+        ASSERT_EQUALS(dirprefix + "cli/main.cpp", it->path());
+        ASSERT_EQUALS(Path::simplifyPath(dirprefix + "cli/main.cpp"), it->spath());
+        ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang());
+        it++;
+        ASSERT_EQUALS(dirprefix + "lib/token.cpp", it->path());
+        ASSERT_EQUALS(Path::simplifyPath(dirprefix + "lib/token.cpp"), it->spath());
+        ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang());
+        it++;
+        ASSERT_EQUALS(dirprefix + "lib/matchcompiler.h", it->path());
+        ASSERT_EQUALS(Path::simplifyPath(dirprefix + "lib/matchcompiler.h"), it->spath());
+        ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang());
+    }
+
     // TODO: test errors
+    // TODO: test wildcards
 };
 
 REGISTER_TEST(TestFileLister)
diff --git a/test/testfilesettings.cpp b/test/testfilesettings.cpp
index 7cf371305ea..63f28d34990 100644
--- a/test/testfilesettings.cpp
+++ b/test/testfilesettings.cpp
@@ -33,36 +33,42 @@ class TestFileSettings : public TestFixture {
             const FileWithDetails p{"file.cpp"};
             ASSERT_EQUALS("file.cpp", p.path());
             ASSERT_EQUALS("file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::None, p.lang());
             ASSERT_EQUALS(0, p.size());
         }
         {
-            const FileWithDetails p{"file.cpp", 123};
+            const FileWithDetails p{"file.cpp", Standards::Language::C, 123};
             ASSERT_EQUALS("file.cpp", p.path());
             ASSERT_EQUALS("file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::C, p.lang());
             ASSERT_EQUALS(123, p.size());
         }
         {
             const FileWithDetails p{"in/file.cpp"};
             ASSERT_EQUALS("in/file.cpp", p.path());
             ASSERT_EQUALS("in/file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::None, p.lang());
             ASSERT_EQUALS(0, p.size());
         }
         {
             const FileWithDetails p{"in\\file.cpp"};
             ASSERT_EQUALS("in\\file.cpp", p.path());
             ASSERT_EQUALS("in/file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::None, p.lang());
             ASSERT_EQUALS(0, p.size());
         }
         {
             const FileWithDetails p{"in/../file.cpp"};
             ASSERT_EQUALS("in/../file.cpp", p.path());
             ASSERT_EQUALS("file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::None, p.lang());
             ASSERT_EQUALS(0, p.size());
         }
         {
             const FileWithDetails p{"in\\..\\file.cpp"};
             ASSERT_EQUALS("in\\..\\file.cpp", p.path());
             ASSERT_EQUALS("file.cpp", p.spath());
+            ASSERT_EQUALS_ENUM(Standards::Language::None, p.lang());
             ASSERT_EQUALS(0, p.size());
         }
     }
diff --git a/test/testpath.cpp b/test/testpath.cpp
index a51037c3081..8e8be2764bb 100644
--- a/test/testpath.cpp
+++ b/test/testpath.cpp
@@ -76,6 +76,16 @@ class TestPath : public TestFixture {
         ASSERT(Path::acceptFile("index")==false);
         ASSERT(Path::acceptFile("")==false);
         ASSERT(Path::acceptFile("C")==false);
+        {
+            Standards::Language lang;
+            ASSERT(Path::acceptFile("index.c", &lang));
+            ASSERT_EQUALS_ENUM(Standards::Language::C, lang);
+        }
+        {
+            Standards::Language lang;
+            ASSERT(Path::acceptFile("index.cpp", &lang));
+            ASSERT_EQUALS_ENUM(Standards::Language::CPP, lang);
+        }
 
         // don't accept any headers
         ASSERT_EQUALS(false, Path::acceptFile("index.h"));
@@ -88,6 +98,21 @@ class TestPath : public TestFixture {
         ASSERT(Path::acceptFile("index.header", extra));
         ASSERT(Path::acceptFile("index.h", extra)==false);
         ASSERT(Path::acceptFile("index.hpp", extra)==false);
+        {
+            Standards::Language lang;
+            ASSERT(Path::acceptFile("index.c", extra, &lang));
+            ASSERT_EQUALS_ENUM(Standards::Language::C, lang);
+        }
+        {
+            Standards::Language lang;
+            ASSERT(Path::acceptFile("index.cpp", extra, &lang));
+            ASSERT_EQUALS_ENUM(Standards::Language::CPP, lang);
+        }
+        {
+            Standards::Language lang;
+            ASSERT(Path::acceptFile("index.extra", extra, &lang));
+            ASSERT_EQUALS_ENUM(Standards::Language::None, lang);
+        }
     }
 
     void getCurrentPath() const {
diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp
index 281a997cc32..280438882f7 100644
--- a/test/testprocessexecutor.cpp
+++ b/test/testprocessexecutor.cpp
@@ -72,18 +72,18 @@ class TestProcessExecutorBase : public TestFixture {
         if (opt.filesList.empty()) {
             for (int i = 1; i <= files; ++i) {
                 std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp";
-                filelist.emplace_back(f_s, data.size());
+                filelist.emplace_back(f_s, Standards::Language::CPP, data.size());
                 if (useFS) {
-                    fileSettings.emplace_back(std::move(f_s), data.size());
+                    fileSettings.emplace_back(std::move(f_s), Standards::Language::CPP, data.size());
                 }
             }
         }
         else {
             for (const auto& f : opt.filesList)
             {
-                filelist.emplace_back(f, data.size());
+                filelist.emplace_back(f, Standards::Language::CPP, data.size());
                 if (useFS) {
-                    fileSettings.emplace_back(f, data.size());
+                    fileSettings.emplace_back(f, Standards::Language::CPP, data.size());
                 }
             }
         }
diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp
index 981eecea339..acc696abad7 100644
--- a/test/testsingleexecutor.cpp
+++ b/test/testsingleexecutor.cpp
@@ -77,19 +77,18 @@ class TestSingleExecutorBase : public TestFixture {
         if (opt.filesList.empty()) {
             for (int i = 1; i <= files; ++i) {
                 std::string f_s = fprefix() + "_" + zpad3(i) + ".cpp";
-                filelist.emplace_back(f_s, data.size());
+                filelist.emplace_back(f_s, Standards::Language::CPP, data.size());
                 if (useFS) {
-                    fileSettings.emplace_back(std::move(f_s), data.size());
+                    fileSettings.emplace_back(std::move(f_s), Standards::Language::CPP, data.size());
                 }
             }
         }
         else {
             for (const auto& f : opt.filesList)
             {
-                filelist.emplace_back(f, data.size());
+                filelist.emplace_back(f, Standards::Language::CPP, data.size());
                 if (useFS) {
-
-                    fileSettings.emplace_back(f, data.size());
+                    fileSettings.emplace_back(f, Standards::Language::CPP, data.size());
                 }
             }
         }
diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp
index 76557a59ee8..8ef15abdbf7 100644
--- a/test/testsuppressions.cpp
+++ b/test/testsuppressions.cpp
@@ -230,9 +230,9 @@ class TestSuppressions : public TestFixture {
 
         std::list<FileWithDetails> filelist;
         for (auto i = f.cbegin(); i != f.cend(); ++i) {
-            filelist.emplace_back(i->first, i->second.size());
+            filelist.emplace_back(i->first, Standards::Language::CPP, i->second.size());
             if (useFS) {
-                fileSettings.emplace_back(i->first, i->second.size());
+                fileSettings.emplace_back(i->first, Standards::Language::CPP, i->second.size());
             }
         }
 
@@ -277,9 +277,9 @@ class TestSuppressions : public TestFixture {
         std::list<FileSettings> fileSettings;
 
         std::list<FileWithDetails> filelist;
-        filelist.emplace_back("test.cpp", strlen(code));
+        filelist.emplace_back("test.cpp", Standards::Language::CPP, strlen(code));
         if (useFS) {
-            fileSettings.emplace_back("test.cpp", strlen(code));
+            fileSettings.emplace_back("test.cpp", Standards::Language::CPP, strlen(code));
         }
 
         /*const*/ auto settings = dinit(Settings,
@@ -321,9 +321,9 @@ class TestSuppressions : public TestFixture {
         std::list<FileSettings> fileSettings;
 
         std::list<FileWithDetails> filelist;
-        filelist.emplace_back("test.cpp", strlen(code));
+        filelist.emplace_back("test.cpp", Standards::Language::CPP, strlen(code));
         if (useFS) {
-            fileSettings.emplace_back("test.cpp", strlen(code));
+            fileSettings.emplace_back("test.cpp", Standards::Language::CPP, strlen(code));
         }
 
         /*const*/ auto settings = dinit(Settings,
diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp
index 43a0fe21d2a..6ac792f6fcf 100644
--- a/test/testthreadexecutor.cpp
+++ b/test/testthreadexecutor.cpp
@@ -72,18 +72,18 @@ class TestThreadExecutorBase : public TestFixture {
         if (opt.filesList.empty()) {
             for (int i = 1; i <= files; ++i) {
                 std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp";
-                filelist.emplace_back(f_s, data.size());
+                filelist.emplace_back(f_s, Standards::Language::CPP, data.size());
                 if (useFS) {
-                    fileSettings.emplace_back(std::move(f_s), data.size());
+                    fileSettings.emplace_back(std::move(f_s), Standards::Language::CPP, data.size());
                 }
             }
         }
         else {
             for (const auto& f : opt.filesList)
             {
-                filelist.emplace_back(f, data.size());
+                filelist.emplace_back(f, Standards::Language::CPP, data.size());
                 if (useFS) {
-                    fileSettings.emplace_back(f, data.size());
+                    fileSettings.emplace_back(f, Standards::Language::CPP, data.size());
                 }
             }
         }