From 4c1c116ca1f096af4eaa2c13e164f6975164cb04 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 24 Sep 2025 19:58:22 +0200 Subject: [PATCH 1/2] added `constness_ptr` as pointer wrapper to ensure actual method constness --- CMakeLists.txt | 2 +- simplecpp.cpp | 47 ++++++++++++++++++++++++++++++++++------------- simplecpp.h | 31 +++++++++++++++---------------- 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a90efae..837d039d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.10) project (simplecpp LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(CheckCXXCompilerFlag) diff --git a/simplecpp.cpp b/simplecpp.cpp index fc145849..bd51d6ba 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -57,6 +57,12 @@ # include #endif +#if __cplusplus >= 201402L +#define SIMPLECPP_PROPAGATE_CONST_GET(t) (t).get() +#else +#define SIMPLECPP_PROPAGATE_CONST_GET(t) (t) +#endif + static bool isHex(const std::string &s) { return s.size()>2 && (s.compare(0,2,"0x")==0 || s.compare(0,2,"0X")==0); @@ -528,9 +534,9 @@ simplecpp::TokenList &simplecpp::TokenList::operator=(TokenList &&other) { if (this != &other) { clear(); - frontToken = other.frontToken; + frontToken = SIMPLECPP_PROPAGATE_CONST_GET(other.frontToken); other.frontToken = nullptr; - backToken = other.backToken; + backToken = SIMPLECPP_PROPAGATE_CONST_GET(other.backToken); other.backToken = nullptr; files = other.files; sizeOfType = std::move(other.sizeOfType); @@ -543,7 +549,7 @@ void simplecpp::TokenList::clear() backToken = nullptr; while (frontToken) { Token * const next = frontToken->next; - delete frontToken; + delete SIMPLECPP_PROPAGATE_CONST_GET(frontToken); frontToken = next; } sizeOfType.clear(); @@ -555,7 +561,7 @@ void simplecpp::TokenList::push_back(Token *tok) frontToken = tok; else backToken->next = tok; - tok->previous = backToken; + tok->previous = SIMPLECPP_PROPAGATE_CONST_GET(backToken); backToken = tok; } @@ -1379,7 +1385,7 @@ void simplecpp::TokenList::constFoldQuestionOp(Token *&tok1) { bool gotoTok1 = false; // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data - for (Token *tok = tok1; tok && tok->op != ')'; tok = gotoTok1 ? tok1 : tok->next) { + for (Token *tok = tok1; tok && tok->op != ')'; tok = gotoTok1 ? tok1 : SIMPLECPP_PROPAGATE_CONST_GET(tok->next)) { gotoTok1 = false; if (tok->str() != "?") continue; @@ -1415,6 +1421,21 @@ void simplecpp::TokenList::removeComments() } } +void simplecpp::TokenList::takeTokens(TokenList &other) +{ + if (!other.frontToken) + return; + if (!frontToken) { + frontToken = SIMPLECPP_PROPAGATE_CONST_GET(other.frontToken); + } else { + backToken->next = SIMPLECPP_PROPAGATE_CONST_GET(other.frontToken); + other.frontToken->previous = SIMPLECPP_PROPAGATE_CONST_GET(backToken); + } + backToken = SIMPLECPP_PROPAGATE_CONST_GET(other.backToken); + other.frontToken = nullptr; + other.backToken = nullptr; +} + std::string simplecpp::TokenList::readUntil(Stream &stream, const Location &location, const char start, const char end, OutputList *outputList) { std::string ret; @@ -1793,7 +1814,7 @@ namespace simplecpp { valueToken = nullptr; return false; } - valueToken = argtok ? argtok->next : nullptr; + valueToken = argtok ? SIMPLECPP_PROPAGATE_CONST_GET(argtok->next) : nullptr; } else { args.clear(); valueToken = nameTokDef->next; @@ -1832,7 +1853,7 @@ namespace simplecpp { tok = tok->next; } if (par != 0) { - const Token *const lastTok = expandValue.back() ? expandValue.back() : valueToken->next; + const Token *const lastTok = expandValue.back() ? expandValue.back() : SIMPLECPP_PROPAGATE_CONST_GET(valueToken->next); throw Error(lastTok->location, "In definition of '" + nameTokDef->str() + "': Missing closing parenthesis for __VA_OPT__"); } } else { @@ -2088,7 +2109,7 @@ namespace simplecpp { } if (!functionLike()) { - for (Token *tok = output_end_1 ? output_end_1->next : output.front(); tok; tok = tok->next) { + for (Token *tok = output_end_1 ? SIMPLECPP_PROPAGATE_CONST_GET(output_end_1->next) : output.front(); tok; tok = tok->next) { tok->macro = nameTokInst->str(); } } @@ -2190,8 +2211,8 @@ namespace simplecpp { if (tok->str() == DEFINED) { const Token * const tok2 = tok->next; - const Token * const tok3 = tok2 ? tok2->next : nullptr; - const Token * const tok4 = tok3 ? tok3->next : nullptr; + const Token * const tok3 = tok2 ? SIMPLECPP_PROPAGATE_CONST_GET(tok2->next) : nullptr; + const Token * const tok4 = tok3 ? SIMPLECPP_PROPAGATE_CONST_GET(tok3->next) : nullptr; const Token *defToken = nullptr; const Token *lastToken = nullptr; if (sameline(tok, tok4) && tok2->op == '(' && tok3->name && tok4->op == ')') { @@ -3243,7 +3264,7 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, filelist.emplace_back(filedata->tokens.front()); } - for (const Token *rawtok = rawtokens.cfront(); rawtok || !filelist.empty(); rawtok = rawtok ? rawtok->next : nullptr) { + for (const Token *rawtok = rawtokens.cfront(); rawtok || !filelist.empty(); rawtok = rawtok ? SIMPLECPP_PROPAGATE_CONST_GET(rawtok->next) : nullptr) { if (rawtok == nullptr) { rawtok = filelist.back(); filelist.pop_back(); @@ -3678,7 +3699,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL expr.push_back(new Token("0", tok->location)); } if (par) - tok = tok ? tok->next : nullptr; + tok = tok ? SIMPLECPP_PROPAGATE_CONST_GET(tok->next) : nullptr; if (!tok || !sameline(rawtok,tok) || (par && tok->op != ')')) { if (outputList) { Output out{ @@ -3721,7 +3742,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } } if (par) - tok = tok ? tok->next : nullptr; + tok = tok ? SIMPLECPP_PROPAGATE_CONST_GET(tok->next) : nullptr; if (!tok || !sameline(rawtok,tok) || (par && tok->op != ')') || (!closingAngularBracket)) { if (outputList) { Output out{ diff --git a/simplecpp.h b/simplecpp.h index f29166ff..0ca20c1d 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -29,6 +29,14 @@ #include #endif +#if __cplusplus >= 201402L +#include + +#define SIMPLECPP_PROPAGATE_CONST(t) std::experimental::propagate_const +#else +#define SIMPLECPP_PROPAGATE_CONST(t) t +#endif + #ifdef _WIN32 # ifdef SIMPLECPP_EXPORT # define SIMPLECPP_LIB __declspec(dllexport) @@ -186,8 +194,8 @@ namespace simplecpp { bool number; bool whitespaceahead; Location location; - Token *previous{}; - Token *next{}; + SIMPLECPP_PROPAGATE_CONST(Token*) previous; + SIMPLECPP_PROPAGATE_CONST(Token*) next; mutable const Token *nextcond{}; const Token *previousSkipComments() const { @@ -356,18 +364,7 @@ namespace simplecpp { delete tok; } - void takeTokens(TokenList &other) { - if (!other.frontToken) - return; - if (!frontToken) { - frontToken = other.frontToken; - } else { - backToken->next = other.frontToken; - other.frontToken->previous = backToken; - } - backToken = other.backToken; - other.frontToken = other.backToken = nullptr; - } + void takeTokens(TokenList &other); /** sizeof(T) */ std::map sizeOfType; @@ -406,8 +403,8 @@ namespace simplecpp { unsigned int fileIndex(const std::string &filename); - Token *frontToken; - Token *backToken; + SIMPLECPP_PROPAGATE_CONST(Token*) frontToken; + SIMPLECPP_PROPAGATE_CONST(Token*) backToken; std::vector &files; }; @@ -634,6 +631,8 @@ namespace simplecpp { # pragma warning(pop) #endif +#undef SIMPLECPP_PROPAGATE_CONST + #undef SIMPLECPP_LIB #endif From faaf5706be5b1d376646949e58cfaf000aa1c670 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 27 Sep 2025 10:48:04 +0200 Subject: [PATCH 2/2] misc-const-correctness --- simplecpp.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index bd51d6ba..c21eff79 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -548,6 +548,7 @@ void simplecpp::TokenList::clear() { backToken = nullptr; while (frontToken) { + // NOLINTNEXTLINE(misc-const-correctness) - FP Token * const next = frontToken->next; delete SIMPLECPP_PROPAGATE_CONST_GET(frontToken); frontToken = next; @@ -1384,7 +1385,6 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok) void simplecpp::TokenList::constFoldQuestionOp(Token *&tok1) { bool gotoTok1 = false; - // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data for (Token *tok = tok1; tok && tok->op != ')'; tok = gotoTok1 ? tok1 : SIMPLECPP_PROPAGATE_CONST_GET(tok->next)) { gotoTok1 = false; if (tok->str() != "?") @@ -2022,7 +2022,6 @@ namespace simplecpp { } } - // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data Token * const output_end_1 = output.back(); const Token *valueToken2;