diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml
index f745a21e177..c69ae08dab0 100644
--- a/.github/workflows/CI-unixish.yml
+++ b/.github/workflows/CI-unixish.yml
@@ -542,7 +542,7 @@ jobs:
./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json --enable=internal lib || ec=1
# check gui with qt settings
mkdir b2
- ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b2 -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1
+ ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b2 -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip --library=qt --addon=naming.json -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1
# self check test and tools
./cppcheck $selfcheck_options $cppcheck_options -Ifrontend -Icli test/*.cpp || ec=1
./cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1
diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml
index d58178a5c1a..fa67e60346a 100644
--- a/.github/workflows/selfcheck.yml
+++ b/.github/workflows/selfcheck.yml
@@ -80,7 +80,7 @@ jobs:
- name: Self check (unusedFunction)
if: false # TODO: fails with preprocessorErrorDirective - see #10667
run: |
- ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr
+ ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip
env:
DISABLE_VALUEFLOW: 1
UNUSEDFUNCTION_ONLY: 1
@@ -105,7 +105,7 @@ jobs:
# TODO: find a way to report unmatched suppressions without need to add information checks
- name: Self check (unusedFunction / no test)
run: |
- ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr
+ ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip
env:
DISABLE_VALUEFLOW: 1
UNUSEDFUNCTION_ONLY: 1
@@ -148,7 +148,7 @@ jobs:
- name: Self check (unusedFunction / no test / no cli)
if: false # TODO: the findings are currently too intrusive
run: |
- ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr
+ ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip
env:
DISABLE_VALUEFLOW: 1
UNUSEDFUNCTION_ONLY: 1
@@ -176,7 +176,7 @@ jobs:
- name: Self check (unusedFunction / corpus / no test / callgrind)
run: |
# TODO: fix -rp so the suppressions actually work
- valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false)
+ valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip 2>callgrind.log || (cat callgrind.log && false)
cat callgrind.log
callgrind_annotate --auto=no > callgrind.annotated.log
head -50 callgrind.annotated.log
diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml
index 11dc26a8ec3..bf84c53a960 100644
--- a/.github/workflows/ubsan.yml
+++ b/.github/workflows/ubsan.yml
@@ -145,7 +145,7 @@ jobs:
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json frontend || ec=1
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -Ifrontend cli || ec=1
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json --enable=internal lib || ec=1
- ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
+ ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA -DQT_FEATURE_shortcut -DQT_FEATURE_tooltip -DQT_FEATURE_statustip --library=qt --addon=naming.json -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli -Ifrontend test/*.cpp || ec=1
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
diff --git a/cfg/qt.cfg b/cfg/qt.cfg
index 12f31c4d0f6..5dc96e95ec7 100644
--- a/cfg/qt.cfg
+++ b/cfg/qt.cfg
@@ -5428,6 +5428,8 @@
+
+
diff --git a/cfg/wxwidgets.cfg b/cfg/wxwidgets.cfg
index 685750f7ff2..a32c1f024a9 100644
--- a/cfg/wxwidgets.cfg
+++ b/cfg/wxwidgets.cfg
@@ -736,6 +736,7 @@
+
diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp
index 599ffdfe408..c0f6e2c01b6 100755
--- a/externals/simplecpp/simplecpp.cpp
+++ b/externals/simplecpp/simplecpp.cpp
@@ -31,12 +31,10 @@
#include
#include
#include
-#if __cplusplus >= 201103L
#ifdef SIMPLECPP_WINDOWS
#include
#endif
#include
-#endif
#include
#include
@@ -51,18 +49,6 @@
#undef ERROR
#endif
-#if __cplusplus >= 201103L
-#define OVERRIDE override
-#define EXPLICIT explicit
-#else
-#define OVERRIDE
-#define EXPLICIT
-#endif
-
-#if (__cplusplus < 201103L) && !defined(__APPLE__)
-#define nullptr NULL
-#endif
-
static bool isHex(const std::string &s)
{
return s.size()>2 && (s.compare(0,2,"0x")==0 || s.compare(0,2,"0X")==0);
@@ -368,22 +354,22 @@ class simplecpp::TokenList::Stream {
class StdIStream : public simplecpp::TokenList::Stream {
public:
// cppcheck-suppress uninitDerivedMemberVar - we call Stream::init() to initialize the private members
- EXPLICIT StdIStream(std::istream &istr)
+ explicit StdIStream(std::istream &istr)
: istr(istr) {
assert(istr.good());
init();
}
- virtual int get() OVERRIDE {
+ virtual int get() override {
return istr.get();
}
- virtual int peek() OVERRIDE {
+ virtual int peek() override {
return istr.peek();
}
- virtual void unget() OVERRIDE {
+ virtual void unget() override {
istr.unget();
}
- virtual bool good() OVERRIDE {
+ virtual bool good() override {
return istr.good();
}
@@ -402,20 +388,20 @@ class StdCharBufStream : public simplecpp::TokenList::Stream {
init();
}
- virtual int get() OVERRIDE {
+ virtual int get() override {
if (pos >= size)
return lastStatus = EOF;
return str[pos++];
}
- virtual int peek() OVERRIDE {
+ virtual int peek() override {
if (pos >= size)
return lastStatus = EOF;
return str[pos];
}
- virtual void unget() OVERRIDE {
+ virtual void unget() override {
--pos;
}
- virtual bool good() OVERRIDE {
+ virtual bool good() override {
return lastStatus != EOF;
}
@@ -429,7 +415,7 @@ class StdCharBufStream : public simplecpp::TokenList::Stream {
class FileStream : public simplecpp::TokenList::Stream {
public:
// cppcheck-suppress uninitDerivedMemberVar - we call Stream::init() to initialize the private members
- EXPLICIT FileStream(const std::string &filename, std::vector &files)
+ explicit FileStream(const std::string &filename, std::vector &files)
: file(fopen(filename.c_str(), "rb"))
, lastCh(0)
, lastStatus(0) {
@@ -440,25 +426,25 @@ class FileStream : public simplecpp::TokenList::Stream {
init();
}
- ~FileStream() OVERRIDE {
+ ~FileStream() override {
fclose(file);
file = nullptr;
}
- virtual int get() OVERRIDE {
+ virtual int get() override {
lastStatus = lastCh = fgetc(file);
return lastCh;
}
- virtual int peek() OVERRIDE{
+ virtual int peek() override{
// keep lastCh intact
const int ch = fgetc(file);
unget_internal(ch);
return ch;
}
- virtual void unget() OVERRIDE {
+ virtual void unget() override {
unget_internal(lastCh);
}
- virtual bool good() OVERRIDE {
+ virtual bool good() override {
return lastStatus != EOF;
}
@@ -519,12 +505,10 @@ simplecpp::TokenList::TokenList(const TokenList &other) : frontToken(nullptr), b
*this = other;
}
-#if __cplusplus >= 201103L
simplecpp::TokenList::TokenList(TokenList &&other) : frontToken(nullptr), backToken(nullptr), files(other.files)
{
*this = std::move(other);
}
-#endif
simplecpp::TokenList::~TokenList()
{
@@ -543,7 +527,6 @@ simplecpp::TokenList &simplecpp::TokenList::operator=(const TokenList &other)
return *this;
}
-#if __cplusplus >= 201103L
simplecpp::TokenList &simplecpp::TokenList::operator=(TokenList &&other)
{
if (this != &other) {
@@ -557,7 +540,6 @@ simplecpp::TokenList &simplecpp::TokenList::operator=(TokenList &&other)
}
return *this;
}
-#endif
void simplecpp::TokenList::clear()
{
@@ -1477,15 +1459,11 @@ unsigned int simplecpp::TokenList::fileIndex(const std::string &filename)
namespace simplecpp {
class Macro;
-#if __cplusplus >= 201103L
using MacroMap = std::unordered_map;
-#else
- typedef std::map MacroMap;
-#endif
class Macro {
public:
- explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(f), variadic(false), valueDefinedInCode_(false) {}
+ explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(f), variadic(false), variadicOpt(false), optExpandValue(nullptr), optNoExpandValue(nullptr), valueDefinedInCode_(false) {}
Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(true) {
if (sameline(tok->previousSkipComments(), tok))
@@ -1515,6 +1493,11 @@ namespace simplecpp {
*this = other;
}
+ ~Macro() {
+ delete optExpandValue;
+ delete optNoExpandValue;
+ }
+
Macro &operator=(const Macro &other) {
if (this != &other) {
files = other.files;
@@ -1707,6 +1690,9 @@ namespace simplecpp {
bool parseDefine(const Token *nametoken) {
nameTokDef = nametoken;
variadic = false;
+ variadicOpt = false;
+ optExpandValue = nullptr;
+ optNoExpandValue = nullptr;
if (!nameTokDef) {
valueToken = endToken = nullptr;
args.clear();
@@ -1744,8 +1730,49 @@ namespace simplecpp {
if (!sameline(valueToken, nameTokDef))
valueToken = nullptr;
endToken = valueToken;
- while (sameline(endToken, nameTokDef))
+ while (sameline(endToken, nameTokDef)) {
+ if (variadic && endToken->str() == "__VA_OPT__")
+ variadicOpt = true;
endToken = endToken->next;
+ }
+
+ if (variadicOpt) {
+ TokenList expandValue(files);
+ TokenList noExpandValue(files);
+ for (const Token *tok = valueToken; tok && tok != endToken;) {
+ if (tok->str() == "__VA_OPT__") {
+ if (!sameline(tok, tok->next) || tok->next->op != '(')
+ throw Error(tok->location, "In definition of '" + nameTokDef->str() + "': Missing opening parenthesis for __VA_OPT__");
+ tok = tok->next->next;
+ int par = 1;
+ while (tok && tok != endToken) {
+ if (tok->op == '(')
+ par++;
+ else if (tok->op == ')')
+ par--;
+ else if (tok->str() == "__VA_OPT__")
+ throw Error(tok->location, "In definition of '" + nameTokDef->str() + "': __VA_OPT__ cannot be nested");
+ if (par == 0) {
+ tok = tok->next;
+ break;
+ }
+ expandValue.push_back(new Token(*tok));
+ tok = tok->next;
+ }
+ if (par != 0) {
+ const Token *const lastTok = expandValue.back() ? expandValue.back() : valueToken->next;
+ throw Error(lastTok->location, "In definition of '" + nameTokDef->str() + "': Missing closing parenthesis for __VA_OPT__");
+ }
+ } else {
+ expandValue.push_back(new Token(*tok));
+ noExpandValue.push_back(new Token(*tok));
+ tok = tok->next;
+ }
+ }
+ optExpandValue = new TokenList(std::move(expandValue));
+ optNoExpandValue = new TokenList(std::move(noExpandValue));
+ }
+
return true;
}
@@ -1900,8 +1927,22 @@ namespace simplecpp {
Token * const output_end_1 = output->back();
+ const Token *valueToken2;
+ const Token *endToken2;
+
+ if (variadicOpt) {
+ if (parametertokens2.size() > args.size() && parametertokens2[args.size() - 1]->next->op != ')')
+ valueToken2 = optExpandValue->cfront();
+ else
+ valueToken2 = optNoExpandValue->cfront();
+ endToken2 = nullptr;
+ } else {
+ valueToken2 = valueToken;
+ endToken2 = endToken;
+ }
+
// expand
- for (const Token *tok = valueToken; tok != endToken;) {
+ for (const Token *tok = valueToken2; tok != endToken2;) {
if (tok->op != '#') {
// A##B => AB
if (sameline(tok, tok->next) && tok->next && tok->next->op == '#' && tok->next->next && tok->next->next->op == '#') {
@@ -1950,7 +1991,7 @@ namespace simplecpp {
}
tok = tok->next;
- if (tok == endToken) {
+ if (tok == endToken2) {
output->push_back(new Token(*tok->previous));
break;
}
@@ -2020,24 +2061,6 @@ namespace simplecpp {
// Macro parameter..
{
TokenList temp(files);
- if (tok->str() == "__VA_OPT__") {
- if (sameline(tok, tok->next) && tok->next->str() == "(") {
- tok = tok->next;
- int paren = 1;
- while (sameline(tok, tok->next)) {
- if (tok->next->str() == "(")
- ++paren;
- else if (tok->next->str() == ")")
- --paren;
- if (paren == 0)
- return tok->next->next;
- tok = tok->next;
- if (parametertokens.size() > args.size() && parametertokens.front()->next->str() != ")")
- tok = expandToken(output, loc, tok, macros, expandedmacros, parametertokens)->previous;
- }
- }
- throw Error(tok->location, "Missing parenthesis for __VA_OPT__(content)");
- }
if (expandArg(&temp, tok, loc, macros, expandedmacros, parametertokens)) {
if (tok->str() == "__VA_ARGS__" && temp.empty() && output->cback() && output->cback()->str() == "," &&
tok->nextSkipComments() && tok->nextSkipComments()->str() == ")")
@@ -2338,6 +2361,13 @@ namespace simplecpp {
/** is macro variadic? */
bool variadic;
+ /** does the macro expansion have __VA_OPT__? */
+ bool variadicOpt;
+
+ /** Expansion value for varadic macros with __VA_OPT__ expanded and discarded respectively */
+ const TokenList *optExpandValue;
+ const TokenList *optNoExpandValue;
+
/** was the value of this macro actually defined in the code? */
bool valueDefinedInCode_;
};
@@ -2380,47 +2410,9 @@ namespace simplecpp {
#ifdef SIMPLECPP_WINDOWS
-#if __cplusplus >= 201103L
using MyMutex = std::mutex;
template
using MyLock = std::lock_guard;
-#else
-class MyMutex {
-public:
- MyMutex() {
- InitializeCriticalSection(&m_criticalSection);
- }
-
- ~MyMutex() {
- DeleteCriticalSection(&m_criticalSection);
- }
-
- CRITICAL_SECTION* lock() {
- return &m_criticalSection;
- }
-private:
- CRITICAL_SECTION m_criticalSection;
-};
-
-template
-class MyLock {
-public:
- explicit MyLock(T& m)
- : m_mutex(m) {
- EnterCriticalSection(m_mutex.lock());
- }
-
- ~MyLock() {
- LeaveCriticalSection(m_mutex.lock());
- }
-
-private:
- MyLock& operator=(const MyLock&);
- MyLock(const MyLock&);
-
- T& m_mutex;
-};
-#endif
class RealFileNameMap {
public:
@@ -2681,13 +2673,16 @@ static void simplifySizeof(simplecpp::TokenList &expr, const std::map= "201703L");
}
+static bool isGnu(const simplecpp::DUI &dui)
+{
+ return dui.std.rfind("gnu", 0) != std::string::npos;
+}
static std::string currentDirectoryOSCalc() {
const std::size_t size = 4096;
@@ -2760,7 +2755,7 @@ static std::string extractRelativePathFromAbsolute(const std::string& absoluteSi
static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader);
static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI &dui)
{
- if (!isCpp17OrLater(dui))
+ if (!isCpp17OrLater(dui) && !isGnu(dui))
return;
for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) {
@@ -2832,6 +2827,8 @@ static void simplifyName(simplecpp::TokenList &expr)
if (alt)
continue;
}
+ if (tok->next && tok->next->str() == "(")
+ throw std::runtime_error("undefined function-like macro invocation: " + tok->str() + "( ... )");
tok->setstr("0");
}
}
@@ -3483,13 +3480,16 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
// use a dummy vector for the macros because as this is not part of the file and would add an empty entry - e.g. /usr/include/poll.h
std::vector dummy;
- const bool hasInclude = isCpp17OrLater(dui);
+ const bool hasInclude = isCpp17OrLater(dui) || isGnu(dui);
MacroMap macros;
+ bool strictAnsiDefined = false;
for (std::list::const_iterator it = dui.defines.begin(); it != dui.defines.end(); ++it) {
const std::string ¯ostr = *it;
const std::string::size_type eq = macrostr.find('=');
const std::string::size_type par = macrostr.find('(');
const std::string macroname = macrostr.substr(0, std::min(eq,par));
+ if (macroname == "__STRICT_ANSI__")
+ strictAnsiDefined = true;
if (dui.undefined.find(macroname) != dui.undefined.end())
continue;
const std::string lhs(macrostr.substr(0,eq));
@@ -3498,6 +3498,10 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
macros.insert(std::pair(macro.name(), macro));
}
+ const bool strictAnsiUndefined = dui.undefined.find("__STRICT_ANSI__") != dui.undefined.cend();
+ if (!isGnu(dui) && !strictAnsiDefined && !strictAnsiUndefined)
+ macros.insert(std::pair("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy)));
+
macros.insert(std::make_pair("__FILE__", Macro("__FILE__", "__FILE__", dummy)));
macros.insert(std::make_pair("__LINE__", Macro("__LINE__", "__LINE__", dummy)));
macros.insert(std::make_pair("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy)));
@@ -3535,6 +3539,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
// AlwaysFalse => drop all code in #if and #else
enum IfState { True, ElseIsTrue, AlwaysFalse };
std::stack ifstates;
+ std::stack iftokens;
ifstates.push(True);
std::stack includetokenstack;
@@ -3621,6 +3626,16 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
}
output.clear();
return;
+ } catch (simplecpp::Macro::Error &err) {
+ if (outputList) {
+ simplecpp::Output out(files);
+ out.type = simplecpp::Output::SYNTAX_ERROR;
+ out.location = err.location;
+ out.msg = "Failed to parse #define, " + err.what;
+ outputList->push_back(out);
+ }
+ output.clear();
+ return;
}
} else if (ifstates.top() == True && rawtok->str() == INCLUDE) {
TokenList inc1(files);
@@ -3848,15 +3863,24 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
ifstates.push(AlwaysFalse);
else
ifstates.push(conditionIsTrue ? True : ElseIsTrue);
+ iftokens.push(rawtok);
} else if (ifstates.top() == True) {
ifstates.top() = AlwaysFalse;
+ iftokens.top()->nextcond = rawtok;
+ iftokens.top() = rawtok;
} else if (ifstates.top() == ElseIsTrue && conditionIsTrue) {
ifstates.top() = True;
+ iftokens.top()->nextcond = rawtok;
+ iftokens.top() = rawtok;
}
} else if (rawtok->str() == ELSE) {
ifstates.top() = (ifstates.top() == ElseIsTrue) ? True : AlwaysFalse;
+ iftokens.top()->nextcond = rawtok;
+ iftokens.top() = rawtok;
} else if (rawtok->str() == ENDIF) {
ifstates.pop();
+ iftokens.top()->nextcond = rawtok;
+ iftokens.pop();
} else if (rawtok->str() == UNDEF) {
if (ifstates.top() == True) {
const Token *tok = rawtok->next;
@@ -3868,7 +3892,10 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
} else if (ifstates.top() == True && rawtok->str() == PRAGMA && rawtok->next && rawtok->next->str() == ONCE && sameline(rawtok,rawtok->next)) {
pragmaOnce.insert(rawtok->location.file());
}
- rawtok = gotoNextLine(rawtok);
+ if (ifstates.top() != True && rawtok->nextcond)
+ rawtok = rawtok->nextcond->previous;
+ else
+ rawtok = gotoNextLine(rawtok);
continue;
}
@@ -4032,7 +4059,3 @@ std::string simplecpp::getCppStdString(const std::string &std)
{
return getCppStdString(getCppStd(std));
}
-
-#if (__cplusplus < 201103L) && !defined(__APPLE__)
-#undef nullptr
-#endif
diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h
index f5c69593cb1..579e6e14ac6 100755
--- a/externals/simplecpp/simplecpp.h
+++ b/externals/simplecpp/simplecpp.h
@@ -27,10 +27,6 @@
# define SIMPLECPP_LIB
#endif
-#if (__cplusplus < 201103L) && !defined(__APPLE__)
-#define nullptr NULL
-#endif
-
#if defined(_MSC_VER)
# pragma warning(push)
// suppress warnings about "conversion from 'type1' to 'type2', possible loss of data"
@@ -100,12 +96,12 @@ namespace simplecpp {
class SIMPLECPP_LIB Token {
public:
Token(const TokenString &s, const Location &loc, bool wsahead = false) :
- whitespaceahead(wsahead), location(loc), previous(nullptr), next(nullptr), string(s) {
+ whitespaceahead(wsahead), location(loc), previous(nullptr), next(nullptr), nextcond(nullptr), string(s) {
flags();
}
Token(const Token &tok) :
- macro(tok.macro), op(tok.op), comment(tok.comment), name(tok.name), number(tok.number), whitespaceahead(tok.whitespaceahead), location(tok.location), previous(nullptr), next(nullptr), string(tok.string), mExpandedFrom(tok.mExpandedFrom) {
+ macro(tok.macro), op(tok.op), comment(tok.comment), name(tok.name), number(tok.number), whitespaceahead(tok.whitespaceahead), location(tok.location), previous(nullptr), next(nullptr), nextcond(nullptr), string(tok.string), mExpandedFrom(tok.mExpandedFrom) {
}
void flags() {
@@ -141,6 +137,7 @@ namespace simplecpp {
Location location;
Token *previous;
Token *next;
+ mutable const Token *nextcond;
const Token *previousSkipComments() const {
const Token *tok = this->previous;
@@ -214,14 +211,10 @@ namespace simplecpp {
/** generates a token list from the given filename parameter */
TokenList(const std::string &filename, std::vector &filenames, OutputList *outputList = nullptr);
TokenList(const TokenList &other);
-#if __cplusplus >= 201103L
TokenList(TokenList &&other);
-#endif
~TokenList();
TokenList &operator=(const TokenList &other);
-#if __cplusplus >= 201103L
TokenList &operator=(TokenList &&other);
-#endif
void clear();
bool empty() const {
@@ -395,8 +388,4 @@ namespace simplecpp {
# pragma warning(pop)
#endif
-#if (__cplusplus < 201103L) && !defined(__APPLE__)
-#undef nullptr
-#endif
-
#endif
diff --git a/test/cli/inline-suppress_test.py b/test/cli/inline-suppress_test.py
index 9c7421656d2..b84f45c209f 100644
--- a/test/cli/inline-suppress_test.py
+++ b/test/cli/inline-suppress_test.py
@@ -32,6 +32,8 @@ def test_1():
'-q',
'--template=simple',
'--inline-suppr',
+ '-DVER_CHECK(...)=0',
+ '--force',
'proj-inline-suppress'
]
ret, stdout, stderr = cppcheck(args, cwd=__script_dir)
@@ -44,6 +46,8 @@ def test_2():
args = [
'-q',
'--template=simple',
+ '-DVER_CHECK(...)=0',
+ '--force',
'proj-inline-suppress'
]
ret, stdout, stderr = cppcheck(args, cwd=__script_dir)
@@ -461,6 +465,8 @@ def test_unmatched_cfg():
'--template=simple',
'--enable=warning,information',
'--inline-suppr',
+ '-DVER_CHECK(...)=0',
+ '--force',
'proj-inline-suppress/cfg.c'
]