diff --git a/addons/misra.py b/addons/misra.py
index ae3cf59c8bc..62a87666490 100755
--- a/addons/misra.py
+++ b/addons/misra.py
@@ -3327,6 +3327,9 @@ def misra_config(self, data):
end_token = tok.link
while tok != end_token:
tok = tok.next
+ if tok.str == 'sizeof' and tok.next.str == '(':
+ tok = tok.next.link
+ continue
if tok.str == "(" and tok.isCast:
tok = tok.link
continue
@@ -4254,6 +4257,7 @@ def setSuppressionList(self, suppressionlist):
self.addSuppressedRule(ruleNum)
def report_config_error(self, location, errmsg):
+ errmsg = 'Because of missing configuration, misra checking is incomplete. There can be false negatives! ' + errmsg
cppcheck_severity = 'error'
error_id = 'config'
if self.settings.verify:
diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c
index d1ece87f2b2..fc0abdab7ca 100644
--- a/addons/test/misra/misra-test.c
+++ b/addons/test/misra/misra-test.c
@@ -2035,3 +2035,13 @@ static void misra_22_10(void)
f = strtod(inStr, NULL_PTR);
if(errno != 0) {}
}
+
+// #12448
+static void check_misra_config(void)
+{
+ if (sizeof(struct bar) == 0U) {} //no warning
+ if (sizeof(int abc) == 0U) {} //no warning
+ if (sizeof(xyz) == 0U) {} //no warning
+ if (sizeof(const pqr) == 0U) {} //no warning
+ if (sizeof(const int* const pqrs) == 0U) {} //no-warning
+}
diff --git a/cfg/std.cfg b/cfg/std.cfg
index 7fb77addfd3..faf23d8f992 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -6428,7 +6428,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
std::istringstream& std::istringstream::get (char* s, streamsize n, char delim);
stream buffer (3) std::istringstream& std::istringstream::get (streambuf& sb);
std::istringstream& std::istringstream::get (streambuf& sb, char delim);-->
-
false
@@ -6509,28 +6509,35 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
false
-
+
false
-
+
false
-
+
false
-
+
+
+
+
+ false
+
+
+
@@ -6566,6 +6573,31 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
0:
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
@@ -8303,7 +8335,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
-
+
false
diff --git a/cfg/windows.cfg b/cfg/windows.cfg
index 63b88dc2af0..fcb9e52106c 100644
--- a/cfg/windows.cfg
+++ b/cfg/windows.cfg
@@ -16895,8 +16895,6 @@ HFONT CreateFont(
-
-
@@ -16917,8 +16915,124 @@ HFONT CreateFont(
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/createrelease b/createrelease
index 2e5828b4c90..71498659bf3 100755
--- a/createrelease
+++ b/createrelease
@@ -7,7 +7,12 @@
#
# check every isPremiumEnabled call:
# - every id should be in --errorlist
+# git grep 'isPremiumEnabled[(]"' | sed 's/.*isPremiumEnabled[(]"//' | sed 's/".*//' | sort | uniq > ids1.txt
+# ./cppcheck --errorlist | grep ' id="' | sed 's/.* id="//' | sed 's/".*//' | sort | uniq > ids2.txt
+# diff -y ids1.txt ids2.txt
# - premiumaddon: check coverage.py
+# python3 coverage.py --id ; sort ids-*.txt | uniq > ~/cppcheck/ids3.txt
+# diff -y ids2.txt ids3.txt
#
# Windows installer:
# - ensure latest build was successful
diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp
index 7ce557bfc92..5aa979b0bcf 100644
--- a/lib/checkfunctions.cpp
+++ b/lib/checkfunctions.cpp
@@ -766,7 +766,7 @@ void CheckFunctions::useStandardLibrary()
continue;
// 3. we expect idx incrementing by 1
- const bool inc = stepToken->str() == "++" && stepToken->astOperand1()->varId() == idxVarId;
+ const bool inc = stepToken->str() == "++" && stepToken->astOperand1() && stepToken->astOperand1()->varId() == idxVarId;
const bool plusOne = stepToken->isBinaryOp() && stepToken->str() == "+=" &&
stepToken->astOperand1()->varId() == idxVarId &&
stepToken->astOperand2()->str() == "1";
diff --git a/lib/checkother.cpp b/lib/checkother.cpp
index 81a55471e7b..7b57eddadbe 100644
--- a/lib/checkother.cpp
+++ b/lib/checkother.cpp
@@ -1958,7 +1958,7 @@ void CheckOther::checkIncompleteStatement()
continue;
if (isVoidStmt(tok))
continue;
- if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral()))
+ if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral()))
// Possible archive
continue;
const bool inconclusive = tok->isConstOp();
diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp
index 8458ffe4d5c..e4038adfbf9 100644
--- a/lib/checkuninitvar.cpp
+++ b/lib/checkuninitvar.cpp
@@ -1287,7 +1287,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library&
if (Token::Match((derefValue ? derefValue : vartok)->astParent(), "(|=") && astIsRhs(derefValue ? derefValue : vartok)) {
const Token *rhstok = derefValue ? derefValue : vartok;
const Token *lhstok = rhstok->astParent()->astOperand1();
- const Variable *lhsvar = lhstok->variable();
+ const Variable *lhsvar = lhstok ? lhstok->variable() : nullptr;
if (lhsvar && lhsvar->isReference() && lhsvar->nameToken() == lhstok)
return nullptr;
}
diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp
index 6b082514f14..b5558233206 100644
--- a/lib/programmemory.cpp
+++ b/lib/programmemory.cpp
@@ -320,7 +320,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke
else
pm.setIntValue(tok, 0, then);
}
- } else if (tok->exprId() > 0) {
+ } else if (tok && tok->exprId() > 0) {
if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings, true))
return;
pm.setIntValue(tok, 0, then);
diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp
index 32b9c921e73..a14b78e7015 100644
--- a/lib/symboldatabase.cpp
+++ b/lib/symboldatabase.cpp
@@ -4281,6 +4281,14 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += accessControlToString(function->access);
outs +="\"";
}
+ if (function->isOperator())
+ outs += " isOperator=\"true\"";
+ if (function->isExplicit())
+ outs += " isExplicit=\"true\"";
+ if (function->hasOverrideSpecifier())
+ outs += " hasOverrideSpecifier=\"true\"";
+ if (function->hasFinalSpecifier())
+ outs += " hasFinalSpecifier=\"true\"";
if (function->isInlineKeyword())
outs += " isInlineKeyword=\"true\"";
if (function->isStatic())
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index 9002f514813..98345dd31f9 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -828,6 +828,8 @@ namespace {
Token* const tok2 = insertTokens(tok, rangeType);
Token* const tok3 = insertTokens(tok2, mRangeTypeQualifiers);
+ tok2->originalName(tok->str());
+ tok3->originalName(tok->str());
Token *after = tok3;
while (Token::Match(after, "%name%|*|&|&&|::"))
after = after->next();
@@ -6342,7 +6344,8 @@ void Tokenizer::removeMacrosInGlobalScope()
while (Token::Match(tok2, "%type% (") && tok2->isUpperCaseName())
tok2 = tok2->linkAt(1)->next();
- if (Token::Match(tok, "%name% (") && Token::Match(tok2, "%name% *|&|::|<| %name%") && !Token::Match(tok2, "namespace|class|struct|union|private:|protected:|public:"))
+ if (Token::Match(tok, "%name% (") && Token::Match(tok2, "%name% *|&|::|<| %name%") &&
+ !Token::Match(tok2, "requires|namespace|class|struct|union|private:|protected:|public:"))
unknownMacroError(tok);
if (Token::Match(tok, "%type% (") && Token::Match(tok2, "%type% (") && !Token::Match(tok2, "noexcept|throw") && isFunctionHead(tok2->next(), ":;{"))
diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp
index a0706491dac..b6e312625d9 100644
--- a/lib/tokenlist.cpp
+++ b/lib/tokenlist.cpp
@@ -960,7 +960,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
Token* const curlyBracket = squareBracket->link()->next();
squareBracket->astOperand1(curlyBracket);
state.op.push(squareBracket);
- tok = curlyBracket->link()->next();
+ tok = curlyBracket->link() ? curlyBracket->link()->next() : nullptr;
continue;
}
}
diff --git a/oss-fuzz/type2.cpp b/oss-fuzz/type2.cpp
index 0fe4ce343c4..6cd3591ec88 100644
--- a/oss-fuzz/type2.cpp
+++ b/oss-fuzz/type2.cpp
@@ -19,7 +19,6 @@
#include "type2.h"
#include
-#include
static int getValue(const uint8_t *data, size_t dataSize, uint8_t maxValue, bool *done = nullptr)
{
@@ -54,19 +53,20 @@ static std::string generateExpression2_lvalue(const uint8_t *data, size_t dataSi
static std::string generateExpression2_Op(const uint8_t *data, size_t dataSize, uint8_t numberOfGlobalConstants)
{
- std::ostringstream code;
+ std::string code;
switch (getValue(data, dataSize, 3)) {
case 0:
- code << generateExpression2_lvalue(data, dataSize);
+ code += generateExpression2_lvalue(data, dataSize);
break;
case 1:
- code << "globalconstant" << (1 + getValue(data, dataSize, numberOfGlobalConstants));
+ code += "globalconstant";
+ code += (1 + getValue(data, dataSize, numberOfGlobalConstants));
break;
case 2:
- code << (getValue(data, dataSize, 0x80) * 0x80 + getValue(data, dataSize, 0x80));
+ code += (getValue(data, dataSize, 0x80) * 0x80 + getValue(data, dataSize, 0x80));
break;
}
- return code.str();
+ return code;
}
static std::string generateExpression2_Expr(const uint8_t *data, size_t dataSize, uint8_t numberOfGlobalConstants, int depth=0)
@@ -130,12 +130,14 @@ static std::string generateExpression2_conditionalCode(const std::string &indent
size_t dataSize,
uint8_t numberOfGlobalConstants)
{
- std::ostringstream code;
+ std::string code;
if (indent.empty())
- code << functionStart();
- else
- code << indent << "{\n";
+ code += functionStart();
+ else {
+ code += indent;
+ code += "{\n";
+ }
for (int line = 0; line < 4 || indent.empty(); ++line) {
bool done = false;
@@ -150,37 +152,60 @@ static std::string generateExpression2_conditionalCode(const std::string &indent
((type1 >= 5) ? mostLikelyType : type1);
if (type2 == 0) {
- code << indent << " var" << getValue(data, dataSize, 5) << "=" << generateExpression2_Expr(data, dataSize, numberOfGlobalConstants) << ";\n";
+ code += indent;
+ code += " var";
+ code += getValue(data, dataSize, 5);
+ code += "=";
+ code += generateExpression2_Expr(data, dataSize, numberOfGlobalConstants);
+ code += ";\n";
} else if (type2 == 1) {
- code << indent << " if (" << generateExpression2_Cond(data, dataSize, numberOfGlobalConstants) << ")\n";
- code << generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
+ code += indent;
+ code += " if (";
+ code += generateExpression2_Cond(data, dataSize, numberOfGlobalConstants);
+ code += ")\n";
+ code += generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
} else if (type2 == 2) {
- code << indent << " if (" << generateExpression2_Cond(data, dataSize, numberOfGlobalConstants) << ")\n";
- code << generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
- code << indent << " else\n";
- code << generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
+ code += indent;
+ code += " if (";
+ code += generateExpression2_Cond(data, dataSize, numberOfGlobalConstants);
+ code += ")\n";
+ code += generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
+ code += indent;
+ code += " else\n";
+ code += generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
} else if (type2 == 3) {
- code << indent << " while (" << generateExpression2_Cond(data, dataSize, numberOfGlobalConstants) << ")\n";
- code << generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
+ code += indent;
+ code += " while (";
+ code += generateExpression2_Cond(data, dataSize, numberOfGlobalConstants);
+ code += ")\n";
+ code += generateExpression2_conditionalCode(indent + " ", data, dataSize, numberOfGlobalConstants);
} else if (type2 == 4) {
- code << indent << " return " << generateExpression2_Expr(data, dataSize, numberOfGlobalConstants) << ";\n";
- if (indent.empty())
- code << "}\n\n" << functionStart();
+ code += indent;
+ code += " return ";
+ code += generateExpression2_Expr(data, dataSize, numberOfGlobalConstants);
+ code += ";\n";
+ if (indent.empty()) {
+ code += "}\n\n";
+ code += functionStart();
+ }
else
break;
}
}
- if (!indent.empty())
- code << indent << "}\n";
- else
- code << " return 0;\n}\n";
- return code.str();
+ if (!indent.empty()) {
+ code += indent;
+ code += "}\n";
+ }
+ else {
+ code += " return 0;\n}\n";
+ }
+ return code;
}
std::string generateCode2(const uint8_t *data, size_t dataSize)
{
- std::ostringstream code;
+ std::string code;
// create global constants
constexpr uint8_t numberOfGlobalConstants = 0;
@@ -192,15 +217,15 @@ std::string generateCode2(const uint8_t *data, size_t dataSize)
}
*/
- code << "int var1 = 1;\n"
- "int var2 = 0;\n"
- "int var3 = 1;\n"
- "int var4 = 0;\n"
- "int var5 = -1;\n\n";
+ code += "int var1 = 1;\n"
+ "int var2 = 0;\n"
+ "int var3 = 1;\n"
+ "int var4 = 0;\n"
+ "int var5 = -1;\n\n";
- code << generateExpression2_conditionalCode("", data, dataSize, numberOfGlobalConstants);
+ code += generateExpression2_conditionalCode("", data, dataSize, numberOfGlobalConstants);
- return code.str();
+ return code;
}
diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp
index 4fab6bb6957..766c3b08efb 100644
--- a/test/cfg/std.cpp
+++ b/test/cfg/std.cpp
@@ -25,6 +25,7 @@
#define __STDC_WANT_LIB_EXT1__ 1
#include
#include
+#include
#include
#include
#include
@@ -53,6 +54,20 @@
#include
#endif
+// https://en.cppreference.com/w/cpp/io/manip/quoted
+void uninitvar_std_quoted(std::stringstream &ss, const std::string &input, const char delim, const char escape)
+{
+ ss << std::quoted(input);
+ ss << std::quoted(input, delim);
+ ss << std::quoted(input, delim, escape);
+ char delimChar;
+ // cppcheck-suppress uninitvar
+ ss << std::quoted(input, delimChar);
+ char escapeChar;
+ // cppcheck-suppress uninitvar
+ ss << std::quoted(input, delim, escapeChar);
+}
+
int zerodiv_ldexp()
{
int i = std::ldexp(0.0, 42.0);
@@ -4936,3 +4951,9 @@ void unique_lock_const_ref(std::mutex& m)
{
std::unique_lock lock(m);
}
+
+void eraseIteratorOutOfBounds_std_deque(std::deque& x) // #8690
+{
+ // cppcheck-suppress eraseIteratorOutOfBounds
+ x.erase(x.end());
+}
\ No newline at end of file
diff --git a/test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83 b/test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83
new file mode 100644
index 00000000000..37965deed0b
Binary files /dev/null and b/test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83 differ
diff --git a/test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba b/test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba
new file mode 100644
index 00000000000..f096de3bf78
Binary files /dev/null and b/test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba differ
diff --git a/test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 b/test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560
new file mode 100644
index 00000000000..80a938891ac
Binary files /dev/null and b/test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 differ
diff --git a/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b b/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b
new file mode 100644
index 00000000000..cf4921c19c7
--- /dev/null
+++ b/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b
@@ -0,0 +1,12 @@
+#include
+sho main()
+{
+ std::veCtor items(2);
+ stdtryector::iterator iter;
+ for (iter -= items.begin(); i&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ter != items.end();) {
+ if (*iter == 2) {
+ iter = items.erase//(iter);
+ } else {
+ }
+ }
+}
diff --git a/test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a b/test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a
new file mode 100644
index 00000000000..89b9bf0f48b
Binary files /dev/null and b/test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a differ
diff --git a/test/cli/fuzz_test.py b/test/cli/fuzz_test.py
new file mode 100644
index 00000000000..91f1dc84a9f
--- /dev/null
+++ b/test/cli/fuzz_test.py
@@ -0,0 +1,16 @@
+import os
+from testutils import cppcheck
+
+__script_dir = os.path.dirname(os.path.abspath(__file__))
+
+
+def test_fuzz_crash():
+ failures = {}
+
+ fuzz_crash_dir = os.path.join(__script_dir, 'fuzz-crash')
+ for f in os.listdir(fuzz_crash_dir):
+ ret, stdout, _ = cppcheck(['-q', '--enable=all', '--inconclusive', f], cwd=fuzz_crash_dir)
+ if ret != 0:
+ failures[f] = stdout
+
+ assert failures == {}
diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp
index b3096edffcb..a63538f346b 100644
--- a/test/testsimplifytypedef.cpp
+++ b/test/testsimplifytypedef.cpp
@@ -230,6 +230,8 @@ class TestSimplifyTypedef : public TestFixture {
TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable
TEST_CASE(simplifyTypedefMacro);
+
+ TEST_CASE(simplifyTypedefOriginalName);
}
#define tok(...) tok_(__FILE__, __LINE__, __VA_ARGS__)
@@ -4131,6 +4133,62 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS("void foo ( uint32_t prev_segment ) { if ( prev_segment == ( ( uint32_t ) 12 ) ) { } }",
simplifyTypedefP(code));
}
+
+ void simplifyTypedefOriginalName() {
+ const char code[] = "typedef unsigned char uint8_t;"
+ "typedef float (*rFunctionPointer_fp)(uint8_t, uint8_t);"
+ "typedef enum eEnumDef {"
+ " ABC = 0,"
+ "}eEnum_t;"
+ "typedef enum {"
+ " ABC = 0,"
+ "}eEnum2_t;"
+ "typedef short int16_t;"
+ "typedef struct stStructDef {"
+ " int16_t swA;"
+ "}stStruct_t;"
+ "double endOfTypeDef;"
+ "eEnum2_t enum2Type;"
+ "stStruct_t structType;"
+ "eEnum_t enumType;"
+ "uint8_t t;"
+ "void test(rFunctionPointer_fp functionPointer);";
+
+ Tokenizer tokenizer(settings1, this);
+ std::istringstream istr(code);
+ tokenizer.list.createTokens(istr, "file.c");
+ tokenizer.createLinks();
+ tokenizer.simplifyTypedef();
+
+ try {
+ tokenizer.validate();
+ }
+ catch (const InternalError&) {
+ ASSERT_EQUALS_MSG(false, true, "Validation of Tokenizer failed");
+ }
+
+ const Token* token;
+ // Get the Token which is at the end of all the Typedef's in this case i placed a variable
+ const Token* endOfTypeDef = Token::findsimplematch(tokenizer.list.front(), "endOfTypeDef", tokenizer.list.back());
+ // Search for the simplified char token and check its original Name
+ token = Token::findsimplematch(endOfTypeDef, "char", tokenizer.list.back());
+ ASSERT_EQUALS("uint8_t", token->originalName());
+ // Search for the simplified eEnumDef token and check its original Name
+ token = Token::findsimplematch(endOfTypeDef, "eEnumDef", tokenizer.list.back());
+ ASSERT_EQUALS("eEnum_t", token->originalName());
+ // Search for the eEnum2_t token as it does not have a name it should be the direct type name
+ token = Token::findsimplematch(endOfTypeDef, "eEnum2_t", tokenizer.list.back());
+ ASSERT_EQUALS("eEnum2_t", token->str());
+ // Search for the simplified stStructDef token and check its original Name
+ token = Token::findsimplematch(endOfTypeDef, "stStructDef", tokenizer.list.back());
+ ASSERT_EQUALS("stStruct_t", token->originalName());
+ // Search for the simplified short token and check its original Name, start from front to get the variable in the struct
+ token = Token::findsimplematch(tokenizer.list.front(), "short", tokenizer.list.back());
+ ASSERT_EQUALS("int16_t", token->originalName());
+ // Search for the simplified * token -> function pointer gets "(*" tokens infront of it
+ token = Token::findsimplematch(endOfTypeDef, "*", tokenizer.list.back());
+ ASSERT_EQUALS("rFunctionPointer_fp", token->originalName());
+ }
};
REGISTER_TEST(TestSimplifyTypedef)
diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp
index 1c42d76fdf9..b3e0818d8e5 100644
--- a/test/testsymboldatabase.cpp
+++ b/test/testsymboldatabase.cpp
@@ -1413,6 +1413,53 @@ class TestSymbolDatabase : public TestFixture {
ASSERT(p->valueType()->volatileness == 2);
ASSERT(p->valueType()->reference == Reference::None);
}
+ {
+ GET_SYMBOL_DB_C("typedef unsigned char uint8_t;\n uint8_t ubVar = 0;\n");
+ const Variable* const p = db->getVariableFromVarId(1);
+ ASSERT(p->valueType());
+ ASSERT(p->valueType()->pointer == 0);
+ ASSERT(p->valueType()->constness == 0);
+ ASSERT(p->valueType()->volatileness == 0);
+ ASSERT(p->valueType()->originalTypeName == "uint8_t");
+ ASSERT(p->valueType()->reference == Reference::None);
+ }
+ {
+ GET_SYMBOL_DB_C("typedef enum eEnumDef {CPPCHECK=0}eEnum_t;\n eEnum_t eVar = CPPCHECK;\n");
+ const Variable* const p = db->getVariableFromVarId(1);
+ ASSERT(p->valueType());
+ ASSERT(p->valueType()->pointer == 0);
+ ASSERT(p->valueType()->constness == 0);
+ ASSERT(p->valueType()->volatileness == 0);
+ ASSERT(p->valueType()->originalTypeName == "eEnum_t");
+ ASSERT(p->valueType()->reference == Reference::None);
+ }
+ {
+ GET_SYMBOL_DB_C("typedef unsigned char uint8_t;\n typedef struct stStructDef {uint8_t ubTest;}stStruct_t;\n stStruct_t stVar;\n");
+ const Variable* p = db->getVariableFromVarId(1);
+ ASSERT(p->valueType());
+ ASSERT(p->valueType()->pointer == 0);
+ ASSERT(p->valueType()->constness == 0);
+ ASSERT(p->valueType()->volatileness == 0);
+ ASSERT(p->valueType()->originalTypeName == "uint8_t");
+ ASSERT(p->valueType()->reference == Reference::None);
+ p = db->getVariableFromVarId(2);
+ ASSERT(p->valueType());
+ ASSERT(p->valueType()->pointer == 0);
+ ASSERT(p->valueType()->constness == 0);
+ ASSERT(p->valueType()->volatileness == 0);
+ ASSERT(p->valueType()->originalTypeName == "stStruct_t");
+ ASSERT(p->valueType()->reference == Reference::None);
+ }
+ {
+ GET_SYMBOL_DB_C("typedef int (*ubFunctionPointer_fp)(int);\n void test(ubFunctionPointer_fp functionPointer);\n");
+ const Variable* const p = db->getVariableFromVarId(1);
+ ASSERT(p->valueType());
+ ASSERT(p->valueType()->pointer == 1);
+ ASSERT(p->valueType()->constness == 0);
+ ASSERT(p->valueType()->volatileness == 0);
+ ASSERT(p->valueType()->originalTypeName == "ubFunctionPointer_fp");
+ ASSERT(p->valueType()->reference == Reference::None);
+ }
}
void VariableValueTypeTemplate() {
diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp
index 03b780eab47..6fa10173b07 100644
--- a/test/testtokenize.cpp
+++ b/test/testtokenize.cpp
@@ -409,6 +409,7 @@ class TestTokenizer : public TestFixture {
TEST_CASE(checkRefQualifiers);
TEST_CASE(checkConditionBlock);
TEST_CASE(checkUnknownCircularVar);
+ TEST_CASE(checkRequires);
// #9052
TEST_CASE(noCrash1);
@@ -7559,6 +7560,12 @@ class TestTokenizer : public TestFixture {
"}\n"));
}
+ void checkRequires()
+ {
+ ASSERT_NO_THROW(tokenizeAndStringify("template\n"
+ "struct X { X(U) requires true {} };\n"));
+ }
+
void noCrash1() {
ASSERT_NO_THROW(tokenizeAndStringify(
"struct A {\n"