@@ -530,6 +530,8 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
530530 if (name.empty ())
531531 return Error (OK);
532532
533+ _functions.insert (name);
534+
533535 for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement (); functionnode; functionnode = functionnode->NextSiblingElement ()) {
534536 const std::string functionnodename = functionnode->Name ();
535537 if (functionnodename == " noreturn" )
@@ -716,18 +718,29 @@ bool Library::isargvalid(const Token *ftok, int argnr, const MathLib::bigint arg
716718 return false ;
717719}
718720
719- static std::string functionName (const Token *ftok, bool *error)
721+ std::string Library::getFunctionName (const Token *ftok, bool *error) const
720722{
721723 if (!ftok) {
722724 *error = true ;
723725 return " " ;
724726 }
725- if (ftok->isName ())
727+ if (ftok->isName ()) {
728+ for (const Scope *scope = ftok->scope (); scope; scope = scope->nestedIn ) {
729+ if (!scope->isClassOrStruct ())
730+ continue ;
731+ for (unsigned int i = 0 ; i < scope->definedType ->derivedFrom .size (); ++i) {
732+ const Type::BaseInfo &baseInfo = scope->definedType ->derivedFrom [i];
733+ const std::string name (baseInfo.name + " ::" + ftok->str ());
734+ if (_functions.find (name) != _functions.end () && matchArguments (ftok, name))
735+ return name;
736+ }
737+ }
726738 return ftok->str ();
739+ }
727740 if (ftok->str () == " ::" ) {
728741 if (!ftok->astOperand2 ())
729- return functionName (ftok->astOperand1 (), error);
730- return functionName (ftok->astOperand1 (),error) + " ::" + functionName (ftok->astOperand2 (),error);
742+ return getFunctionName (ftok->astOperand1 (), error);
743+ return getFunctionName (ftok->astOperand1 (),error) + " ::" + getFunctionName (ftok->astOperand2 (),error);
731744 }
732745 if (ftok->str () == " ." && ftok->astOperand1 ()) {
733746 const std::string type = astCanonicalType (ftok->astOperand1 ());
@@ -736,21 +749,21 @@ static std::string functionName(const Token *ftok, bool *error)
736749 return " " ;
737750 }
738751
739- return type + " ::" + functionName (ftok->astOperand2 (),error);
752+ return type + " ::" + getFunctionName (ftok->astOperand2 (),error);
740753 }
741754 *error = true ;
742755 return " " ;
743756}
744757
745- static std::string functionName (const Token *ftok)
758+ std::string Library::getFunctionName (const Token *ftok) const
746759{
747760 if (!Token::Match (ftok, " %name% (" ))
748761 return " " ;
749762
750763 // Lookup function name using AST..
751764 if (ftok->astParent ()) {
752765 bool error = false ;
753- std::string ret = functionName (ftok->next ()->astOperand1 (), &error);
766+ std::string ret = getFunctionName (ftok->next ()->astOperand1 (), &error);
754767 return error ? std::string () : ret;
755768 }
756769
@@ -773,7 +786,7 @@ bool Library::isnullargbad(const Token *ftok, int argnr) const
773786 const ArgumentChecks *arg = getarg (ftok, argnr);
774787 if (!arg) {
775788 // scan format string argument should not be null
776- const std::string funcname = functionName (ftok);
789+ const std::string funcname = getFunctionName (ftok);
777790 std::map<std::string, std::pair<bool , bool > >::const_iterator it = _formatstr.find (funcname);
778791 if (it != _formatstr.end () && it->second .first )
779792 return true ;
@@ -786,7 +799,7 @@ bool Library::isuninitargbad(const Token *ftok, int argnr) const
786799 const ArgumentChecks *arg = getarg (ftok, argnr);
787800 if (!arg) {
788801 // non-scan format string argument should not be uninitialized
789- const std::string funcname = functionName (ftok);
802+ const std::string funcname = getFunctionName (ftok);
790803 std::map<std::string, std::pair<bool , bool > >::const_iterator it = _formatstr.find (funcname);
791804 if (it != _formatstr.end () && !it->second .first )
792805 return true ;
@@ -798,14 +811,14 @@ bool Library::isuninitargbad(const Token *ftok, int argnr) const
798811/* * get allocation info for function */
799812const Library::AllocFunc* Library::alloc (const Token *tok) const
800813{
801- const std::string funcname = functionName (tok);
814+ const std::string funcname = getFunctionName (tok);
802815 return isNotLibraryFunction (tok) && argumentChecks.find (funcname) != argumentChecks.end () ? 0 : getAllocDealloc (_alloc, funcname);
803816}
804817
805818/* * get deallocation info for function */
806819const Library::AllocFunc* Library::dealloc (const Token *tok) const
807820{
808- const std::string funcname = functionName (tok);
821+ const std::string funcname = getFunctionName (tok);
809822 return isNotLibraryFunction (tok) && argumentChecks.find (funcname) != argumentChecks.end () ? 0 : getAllocDealloc (_dealloc, funcname);
810823}
811824
@@ -829,7 +842,7 @@ const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) co
829842 if (isNotLibraryFunction (ftok))
830843 return nullptr ;
831844 std::map<std::string, std::map<int , ArgumentChecks> >::const_iterator it1;
832- it1 = argumentChecks.find (functionName (ftok));
845+ it1 = argumentChecks.find (getFunctionName (ftok));
833846 if (it1 == argumentChecks.end ())
834847 return nullptr ;
835848 const std::map<int ,ArgumentChecks>::const_iterator it2 = it1->second .find (argnr);
@@ -906,10 +919,15 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
906919 if (ftok->varId ())
907920 return true ;
908921
922+ return !matchArguments (ftok, getFunctionName (ftok));
923+ }
924+
925+ bool Library::matchArguments (const Token *ftok, const std::string &functionName) const
926+ {
909927 int callargs = numberOfArguments (ftok);
910- const std::map<std::string, std::map<int , ArgumentChecks> >::const_iterator it = argumentChecks.find (functionName (ftok) );
928+ const std::map<std::string, std::map<int , ArgumentChecks> >::const_iterator it = argumentChecks.find (functionName);
911929 if (it == argumentChecks.end ())
912- return (callargs ! = 0 );
930+ return (callargs = = 0 );
913931 int args = 0 ;
914932 int firstOptionalArg = -1 ;
915933 for (std::map<int , ArgumentChecks>::const_iterator it2 = it->second .begin (); it2 != it->second .end (); ++it2) {
@@ -919,16 +937,16 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
919937 firstOptionalArg = it2->first ;
920938
921939 if (it2->second .formatstr )
922- return args > callargs;
940+ return args <= callargs;
923941 }
924- return (firstOptionalArg < 0 ) ? args != callargs : ! (callargs >= firstOptionalArg-1 && callargs <= args);
942+ return (firstOptionalArg < 0 ) ? args == callargs : (callargs >= firstOptionalArg-1 && callargs <= args);
925943}
926944
927945const Library::WarnInfo* Library::getWarnInfo (const Token* ftok) const
928946{
929947 if (isNotLibraryFunction (ftok))
930948 return nullptr ;
931- std::map<std::string, WarnInfo>::const_iterator i = functionwarn.find (functionName (ftok));
949+ std::map<std::string, WarnInfo>::const_iterator i = functionwarn.find (getFunctionName (ftok));
932950 if (i == functionwarn.cend ())
933951 return nullptr ;
934952 return &i->second ;
@@ -937,12 +955,12 @@ const Library::WarnInfo* Library::getWarnInfo(const Token* ftok) const
937955bool Library::formatstr_function (const Token* ftok) const
938956{
939957 return (!isNotLibraryFunction (ftok) &&
940- _formatstr.find (functionName (ftok)) != _formatstr.cend ());
958+ _formatstr.find (getFunctionName (ftok)) != _formatstr.cend ());
941959}
942960
943961int Library::formatstr_argno (const Token* ftok) const
944962{
945- const std::map<int , Library::ArgumentChecks>& argumentChecksFunc = argumentChecks.at (functionName (ftok));
963+ const std::map<int , Library::ArgumentChecks>& argumentChecksFunc = argumentChecks.at (getFunctionName (ftok));
946964 for (std::map<int , Library::ArgumentChecks>::const_iterator i = argumentChecksFunc.cbegin (); i != argumentChecksFunc.cend (); ++i) {
947965 if (i->second .formatstr ) {
948966 return i->first - 1 ;
@@ -953,18 +971,18 @@ int Library::formatstr_argno(const Token* ftok) const
953971
954972bool Library::formatstr_scan (const Token* ftok) const
955973{
956- return _formatstr.at (functionName (ftok)).first ;
974+ return _formatstr.at (getFunctionName (ftok)).first ;
957975}
958976
959977bool Library::formatstr_secure (const Token* ftok) const
960978{
961- return _formatstr.at (functionName (ftok)).second ;
979+ return _formatstr.at (getFunctionName (ftok)).second ;
962980}
963981
964982bool Library::isUseRetVal (const Token* ftok) const
965983{
966984 return (!isNotLibraryFunction (ftok) &&
967- _useretval.find (functionName (ftok)) != _useretval.end ());
985+ _useretval.find (getFunctionName (ftok)) != _useretval.end ());
968986}
969987
970988bool Library::isnoreturn (const Token *ftok) const
@@ -973,7 +991,7 @@ bool Library::isnoreturn(const Token *ftok) const
973991 return true ;
974992 if (isNotLibraryFunction (ftok))
975993 return false ;
976- std::map<std::string, bool >::const_iterator it = _noreturn.find (functionName (ftok));
994+ std::map<std::string, bool >::const_iterator it = _noreturn.find (getFunctionName (ftok));
977995 return (it != _noreturn.end () && it->second );
978996}
979997
@@ -983,7 +1001,7 @@ bool Library::isnotnoreturn(const Token *ftok) const
9831001 return false ;
9841002 if (isNotLibraryFunction (ftok))
9851003 return false ;
986- std::map<std::string, bool >::const_iterator it = _noreturn.find (functionName (ftok));
1004+ std::map<std::string, bool >::const_iterator it = _noreturn.find (getFunctionName (ftok));
9871005 return (it != _noreturn.end () && !it->second );
9881006}
9891007
0 commit comments