Skip to content

Commit 0ccd18a

Browse files
committed
Fix #14113
1 parent 86f4c91 commit 0ccd18a

14 files changed

Lines changed: 392 additions & 283 deletions

.github/workflows/selfcheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ jobs:
121121
122122
- name: Self check (unusedFunction / no test / no gui)
123123
run: |
124-
supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695"
124+
supprs="--suppress=unusedFunction:lib/errorlogger.h:198 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695"
125125
./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs
126126
env:
127127
DISABLE_VALUEFLOW: 1

.selfcheck_suppressions

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ templateInstantiation:test/testutils.cpp
6262

6363
naming-varname:externals/simplecpp/simplecpp.h
6464
naming-privateMemberVariable:externals/simplecpp/simplecpp.h
65+
# false positive; lambda captures its owner
66+
danglingLifetime:externals/simplecpp/simplecpp.h:512
6567

6668
# TODO: these warnings need to be addressed upstream
6769
uninitMemberVar:externals/tinyxml2/tinyxml2.h

externals/simplecpp/simplecpp.cpp

Lines changed: 126 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,12 @@
33
* Copyright (C) 2016-2023 simplecpp team
44
*/
55

6+
// needs to be specified here otherwise _mingw.h will define it as 0x0601
7+
// causing FileIdInfo not to be available
68
#if defined(_WIN32)
79
# ifndef _WIN32_WINNT
810
# define _WIN32_WINNT 0x0602
911
# endif
10-
# ifndef NOMINMAX
11-
# define NOMINMAX
12-
# endif
13-
# ifndef WIN32_LEAN_AND_MEAN
14-
# define WIN32_LEAN_AND_MEAN
15-
# endif
16-
# include <windows.h>
17-
# undef ERROR
1812
#endif
1913

2014
#include "simplecpp.h"
@@ -51,10 +45,19 @@
5145
#include <utility>
5246
#include <vector>
5347

54-
#ifdef _WIN32
48+
#if defined(_WIN32)
49+
# ifndef NOMINMAX
50+
# define NOMINMAX
51+
# endif
52+
# ifndef WIN32_LEAN_AND_MEAN
53+
# define WIN32_LEAN_AND_MEAN
54+
# endif
55+
# include <windows.h>
56+
# undef ERROR
5557
# include <direct.h>
5658
#else
5759
# include <sys/stat.h>
60+
# include <sys/types.h>
5861
#endif
5962

6063
static bool isHex(const std::string &s)
@@ -658,8 +661,6 @@ static const std::string COMMENT_END("*/");
658661

659662
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList)
660663
{
661-
std::stack<simplecpp::Location> loc;
662-
663664
unsigned int multiline = 0U;
664665

665666
const Token *oldLastToken = nullptr;
@@ -698,59 +699,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
698699

699700
if (oldLastToken != cback()) {
700701
oldLastToken = cback();
701-
const Token * const llTok = isLastLinePreprocessor();
702-
if (!llTok)
702+
703+
// #line 3
704+
// #line 3 "file.c"
705+
// #3
706+
// #3 "file.c"
707+
const Token * ppTok = isLastLinePreprocessor();
708+
if (!ppTok)
703709
continue;
704-
const Token * const llNextToken = llTok->next;
705-
if (!llTok->next)
710+
711+
const auto advanceAndSkipComments = [](const Token* tok) {
712+
do {
713+
tok = tok->next;
714+
} while (tok && tok->comment);
715+
return tok;
716+
};
717+
718+
// skip #
719+
ppTok = advanceAndSkipComments(ppTok);
720+
if (!ppTok)
706721
continue;
707-
if (llNextToken->next) {
708-
// #file "file.c"
709-
if (llNextToken->str() == "file" &&
710-
llNextToken->next->str()[0] == '\"')
711-
{
712-
const Token *strtok = cback();
713-
while (strtok->comment)
714-
strtok = strtok->previous;
715-
loc.push(location);
716-
location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U));
717-
location.line = 1U;
718-
}
719-
// TODO: add support for "# 3"
720-
// #3 "file.c"
721-
// #line 3 "file.c"
722-
else if ((llNextToken->number &&
723-
llNextToken->next->str()[0] == '\"') ||
724-
(llNextToken->str() == "line" &&
725-
llNextToken->next->number &&
726-
llNextToken->next->next &&
727-
llNextToken->next->next->str()[0] == '\"'))
728-
{
729-
const Token *strtok = cback();
730-
while (strtok->comment)
731-
strtok = strtok->previous;
732-
const Token *numtok = strtok->previous;
733-
while (numtok->comment)
734-
numtok = numtok->previous;
735-
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
736-
std::atol(numtok->str().c_str()), location);
737-
}
738-
// #line 3
739-
else if (llNextToken->str() == "line" &&
740-
llNextToken->next->number)
741-
{
742-
const Token *numtok = cback();
743-
while (numtok->comment)
744-
numtok = numtok->previous;
745-
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), location);
746-
}
747-
}
748-
// #endfile
749-
else if (llNextToken->str() == "endfile" && !loc.empty())
750-
{
751-
location = loc.top();
752-
loc.pop();
753-
}
722+
723+
if (ppTok->str() == "line")
724+
ppTok = advanceAndSkipComments(ppTok);
725+
726+
if (!ppTok || !ppTok->number)
727+
continue;
728+
729+
const unsigned int line = std::atol(ppTok->str().c_str());
730+
ppTok = advanceAndSkipComments(ppTok);
731+
732+
unsigned int fileindex;
733+
734+
if (ppTok && ppTok->str()[0] == '\"')
735+
fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\"));
736+
else
737+
fileindex = location.fileIndex;
738+
739+
lineDirective(fileindex, line, location);
754740
}
755741

756742
continue;
@@ -1040,7 +1026,7 @@ void simplecpp::TokenList::combineOperators()
10401026
continue;
10411027
}
10421028
const Token *prev = tok->previous;
1043-
while (prev && prev->isOneOf(";{}()"))
1029+
while (prev && prev->isOneOf(";{}("))
10441030
prev = prev->previous;
10451031
executableScope.push(prev && prev->op == ')');
10461032
continue;
@@ -2332,9 +2318,6 @@ namespace simplecpp {
23322318
const Token *nextTok = B->next;
23332319

23342320
if (canBeConcatenatedStringOrChar) {
2335-
if (unexpectedA)
2336-
throw invalidHashHash::unexpectedToken(tok->location, name(), A);
2337-
23382321
// It seems clearer to handle this case separately even though the code is similar-ish, but we don't want to merge here.
23392322
// TODO The question is whether the ## or varargs may still apply, and how to provoke?
23402323
if (expandArg(tokensB, B, parametertokens)) {
@@ -3090,6 +3073,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30903073
return "";
30913074
}
30923075

3076+
namespace {
3077+
struct FileID {
3078+
#ifdef _WIN32
3079+
struct {
3080+
std::uint64_t VolumeSerialNumber;
3081+
struct {
3082+
std::uint64_t IdentifierHi;
3083+
std::uint64_t IdentifierLo;
3084+
} FileId;
3085+
} fileIdInfo;
3086+
3087+
bool operator==(const FileID &that) const noexcept {
3088+
return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber &&
3089+
fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi &&
3090+
fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo;
3091+
}
3092+
#else
3093+
dev_t dev;
3094+
ino_t ino;
3095+
3096+
bool operator==(const FileID& that) const noexcept {
3097+
return dev == that.dev && ino == that.ino;
3098+
}
3099+
#endif
3100+
struct Hasher {
3101+
std::size_t operator()(const FileID &id) const {
3102+
#ifdef _WIN32
3103+
return static_cast<std::size_t>(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^
3104+
id.fileIdInfo.VolumeSerialNumber);
3105+
#else
3106+
return static_cast<std::size_t>(id.dev) ^ static_cast<std::size_t>(id.ino);
3107+
#endif
3108+
}
3109+
};
3110+
};
3111+
}
3112+
3113+
struct simplecpp::FileDataCache::Impl
3114+
{
3115+
void clear()
3116+
{
3117+
mIdMap.clear();
3118+
}
3119+
3120+
using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3121+
3122+
id_map_type mIdMap;
3123+
};
3124+
3125+
simplecpp::FileDataCache::FileDataCache()
3126+
: mImpl(new Impl)
3127+
{}
3128+
3129+
simplecpp::FileDataCache::~FileDataCache() = default;
3130+
simplecpp::FileDataCache::FileDataCache(FileDataCache &&) noexcept = default;
3131+
simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) noexcept = default;
3132+
3133+
static bool getFileId(const std::string &path, FileID &id);
3134+
30933135
std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDataCache::name_map_type::iterator &name_it, const simplecpp::DUI &dui, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
30943136
{
30953137
const std::string &path = name_it->first;
@@ -3098,8 +3140,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30983140
if (!getFileId(path, fileId))
30993141
return {nullptr, false};
31003142

3101-
const auto id_it = mIdMap.find(fileId);
3102-
if (id_it != mIdMap.end()) {
3143+
const auto id_it = mImpl->mIdMap.find(fileId);
3144+
if (id_it != mImpl->mIdMap.end()) {
31033145
name_it->second = id_it->second;
31043146
return {id_it->second, false};
31053147
}
@@ -3110,9 +3152,12 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
31103152
data->tokens.removeComments();
31113153

31123154
name_it->second = data;
3113-
mIdMap.emplace(fileId, data);
3155+
mImpl->mIdMap.emplace(fileId, data);
31143156
mData.emplace_back(data);
31153157

3158+
if (mLoadCallback)
3159+
mLoadCallback(*data);
3160+
31163161
return {data, true};
31173162
}
31183163

@@ -3162,7 +3207,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31623207
return {nullptr, false};
31633208
}
31643209

3165-
bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
3210+
void simplecpp::FileDataCache::clear()
3211+
{
3212+
mImpl->clear();
3213+
mNameMap.clear();
3214+
mData.clear();
3215+
}
3216+
3217+
static bool getFileId(const std::string &path, FileID &id)
31663218
{
31673219
#ifdef _WIN32
31683220
HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
@@ -3349,20 +3401,20 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
33493401
std::map<std::string, std::size_t> sizeOfType(rawtokens.sizeOfType);
33503402
sizeOfType.insert(std::make_pair("char", sizeof(char)));
33513403
sizeOfType.insert(std::make_pair("short", sizeof(short)));
3352-
sizeOfType.insert(std::make_pair("short int", sizeOfType["short"]));
3404+
sizeOfType.insert(std::make_pair("short int", sizeof(short)));
33533405
sizeOfType.insert(std::make_pair("int", sizeof(int)));
33543406
sizeOfType.insert(std::make_pair("long", sizeof(long)));
3355-
sizeOfType.insert(std::make_pair("long int", sizeOfType["long"]));
3407+
sizeOfType.insert(std::make_pair("long int", sizeof(long)));
33563408
sizeOfType.insert(std::make_pair("long long", sizeof(long long)));
33573409
sizeOfType.insert(std::make_pair("float", sizeof(float)));
33583410
sizeOfType.insert(std::make_pair("double", sizeof(double)));
33593411
sizeOfType.insert(std::make_pair("long double", sizeof(long double)));
33603412
sizeOfType.insert(std::make_pair("char *", sizeof(char *)));
33613413
sizeOfType.insert(std::make_pair("short *", sizeof(short *)));
3362-
sizeOfType.insert(std::make_pair("short int *", sizeOfType["short *"]));
3414+
sizeOfType.insert(std::make_pair("short int *", sizeof(short *)));
33633415
sizeOfType.insert(std::make_pair("int *", sizeof(int *)));
33643416
sizeOfType.insert(std::make_pair("long *", sizeof(long *)));
3365-
sizeOfType.insert(std::make_pair("long int *", sizeOfType["long *"]));
3417+
sizeOfType.insert(std::make_pair("long int *", sizeof(long *)));
33663418
sizeOfType.insert(std::make_pair("long long *", sizeof(long long *)));
33673419
sizeOfType.insert(std::make_pair("float *", sizeof(float *)));
33683420
sizeOfType.insert(std::make_pair("double *", sizeof(double *)));

0 commit comments

Comments
 (0)