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),