diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng
index 4949ef15c..004e931b4 100644
--- a/cfg/cppcheck-cfg.rng
+++ b/cfg/cppcheck-cfg.rng
@@ -498,6 +498,11 @@
+
+
+
+
+
diff --git a/cfg/std.cfg b/cfg/std.cfg
index cd84c30c0..b40a500be 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -6600,15 +6600,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
-
-
-
-
-
-
- false
-
@@ -6676,7 +6667,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
+
@@ -6969,12 +6960,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
0:
-
-
-
-
- false
-
@@ -8589,8 +8574,8 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
-
-
+
+
@@ -8640,7 +8625,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
-
+
@@ -8750,6 +8735,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
+
@@ -8757,7 +8743,6 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
-
diff --git a/lib/library.cpp b/lib/library.cpp
index 2f7c6e0dc..c80c94f88 100644
--- a/lib/library.cpp
+++ b/lib/library.cpp
@@ -484,6 +484,10 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, yieldName);
}
+ const char* const returnType = functionNode->Attribute("returnType");
+ if (returnType)
+ container.functions[functionName].returnType = returnType;
+
container.functions[functionName].action = action;
container.functions[functionName].yield = yield;
}
@@ -905,6 +909,10 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, yieldName);
}
func.containerYield = yield;
+
+ const char* const returnType = functionnode->Attribute("returnType");
+ if (returnType)
+ func.returnType = returnType;
} else
unknown_elements.insert(functionnodename);
}
@@ -1358,17 +1366,18 @@ const Library::NonOverlappingData* Library::getNonOverlappingData(const Token *f
Library::UseRetValType Library::getUseRetValType(const Token *ftok) const
{
- if (Token::simpleMatch(ftok->astParent(), ".")) {
- using Yield = Library::Container::Yield;
- using Action = Library::Container::Action;
- const Yield yield = astContainerYield(ftok->astParent()->astOperand1());
- if (yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR || yield == Yield::AT_INDEX ||
- yield == Yield::SIZE || yield == Yield::EMPTY || yield == Yield::BUFFER || yield == Yield::BUFFER_NT ||
- ((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(ftok->astParent()->astOperand1()) == Action::NO_ACTION))
- return Library::UseRetValType::DEFAULT;
- }
- if (isNotLibraryFunction(ftok))
+ if (isNotLibraryFunction(ftok)) {
+ if (Token::simpleMatch(ftok->astParent(), ".")) {
+ const Token* contTok = ftok->astParent()->astOperand1();
+ using Yield = Library::Container::Yield;
+ const Yield yield = astContainerYield(contTok);
+ if (yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR || yield == Yield::AT_INDEX ||
+ yield == Yield::SIZE || yield == Yield::EMPTY || yield == Yield::BUFFER || yield == Yield::BUFFER_NT ||
+ ((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(contTok) == Library::Container::Action::NO_ACTION))
+ return Library::UseRetValType::DEFAULT;
+ }
return Library::UseRetValType::NONE;
+ }
const std::unordered_map::const_iterator it = functions.find(getFunctionName(ftok));
if (it != functions.cend())
return it->second.useretval;
@@ -1385,8 +1394,14 @@ const std::string& Library::returnValue(const Token *ftok) const
const std::string& Library::returnValueType(const Token *ftok) const
{
- if (isNotLibraryFunction(ftok))
+ if (isNotLibraryFunction(ftok)) {
+ if (Token::simpleMatch(ftok->astParent(), ".") && ftok->astParent()->astOperand1()) {
+ const Token* contTok = ftok->astParent()->astOperand1();
+ if (contTok->valueType() && contTok->valueType()->container)
+ return contTok->valueType()->container->getReturnType(ftok->str());
+ }
return emptyString;
+ }
const std::map::const_iterator it = mReturnValueType.find(getFunctionName(ftok));
return it != mReturnValueType.cend() ? it->second : emptyString;
}
@@ -1479,8 +1494,15 @@ bool Library::isFunctionConst(const Token *ftok) const
{
if (ftok->function() && ftok->function()->isConst())
return true;
- if (isNotLibraryFunction(ftok))
+ if (isNotLibraryFunction(ftok)) {
+ if (Token::simpleMatch(ftok->astParent(), ".")) {
+ using Yield = Library::Container::Yield;
+ const Yield yield = astContainerYield(ftok->astParent()->astOperand1());
+ if (yield == Yield::EMPTY || yield == Yield::SIZE || yield == Yield::BUFFER_NT)
+ return true;
+ }
return false;
+ }
const std::unordered_map::const_iterator it = functions.find(getFunctionName(ftok));
return (it != functions.cend() && it->second.isconst);
}
@@ -1489,8 +1511,15 @@ bool Library::isnoreturn(const Token *ftok) const
{
if (ftok->function() && ftok->function()->isAttributeNoreturn())
return true;
- if (isNotLibraryFunction(ftok))
+ if (isNotLibraryFunction(ftok)) {
+ if (Token::simpleMatch(ftok->astParent(), ".")) {
+ const Token* contTok = ftok->astParent()->astOperand1();
+ if (astContainerAction(contTok) != Library::Container::Action::NO_ACTION ||
+ astContainerYield(contTok) != Library::Container::Yield::NO_YIELD)
+ return false;
+ }
return false;
+ }
const std::unordered_map::const_iterator it = mNoReturn.find(getFunctionName(ftok));
if (it == mNoReturn.end())
return false;
diff --git a/lib/library.h b/lib/library.h
index 306f86ac6..2e38a7332 100644
--- a/lib/library.h
+++ b/lib/library.h
@@ -251,6 +251,7 @@ public:
struct Function {
Action action;
Yield yield;
+ std::string returnType;
};
struct RangeItemRecordTypeItem {
std::string name;
@@ -284,6 +285,11 @@ public:
return Yield::NO_YIELD;
}
+ const std::string& getReturnType(const std::string& function) const {
+ auto i = functions.find(function);
+ return (i != functions.end()) ? i->second.returnType : emptyString;
+ }
+
static Yield yieldFrom(const std::string& yieldName);
static Action actionFrom(const std::string& actionName);
};
@@ -359,6 +365,7 @@ public:
bool formatstr_secure;
Container::Action containerAction;
Container::Yield containerYield;
+ std::string returnType;
Function()
: use(false),
leakignore(false),