@@ -758,6 +758,32 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
758758
759759 // Check struct..
760760 int indentlevel2 = 0 ;
761+
762+ auto deallocInFunction = [this ](const Token* tok, int structid) -> bool {
763+ // Calling non-function / function that doesn't deallocate?
764+ if (CheckMemoryLeakInFunction::test_white_list (tok->str (), mSettings , mTokenizer ->isCPP ()))
765+ return false ;
766+
767+ // Check if the struct is used..
768+ bool deallocated = false ;
769+ const Token* const end = tok->linkAt (1 );
770+ for (const Token* tok2 = tok; tok2 != end; tok2 = tok2->next ()) {
771+ if (Token::Match (tok2, " [(,] &| %varid% [,)]" , structid)) {
772+ /* * @todo check if the function deallocates the memory */
773+ deallocated = true ;
774+ break ;
775+ }
776+
777+ if (Token::Match (tok2, " [(,] &| %varid% . %name% [,)]" , structid)) {
778+ /* * @todo check if the function deallocates the memory */
779+ deallocated = true ;
780+ break ;
781+ }
782+ };
783+
784+ return deallocated;
785+ };
786+
761787 for (const Token *tok2 = variable->nameToken (); tok2 && tok2 != variable->scope ()->bodyEnd ; tok2 = tok2->next ()) {
762788 if (tok2->str () == " {" )
763789 ++indentlevel2;
@@ -867,7 +893,8 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
867893 // Returning from function without deallocating struct member?
868894 if (!Token::Match (tok3, " return %varid% ;" , structid) &&
869895 !Token::Match (tok3, " return & %varid%" , structid) &&
870- !(Token::Match (tok3, " return %varid% . %var%" , structid) && tok3->tokAt (3 )->varId () == structmemberid)) {
896+ !(Token::Match (tok3, " return %varid% . %var%" , structid) && tok3->tokAt (3 )->varId () == structmemberid) &&
897+ !(Token::Match (tok3, " return %name% (" ) && tok3->astOperand1 () && deallocInFunction (tok3->astOperand1 (), structid))) {
871898 memoryLeak (tok3, variable->name () + " ." + tok2->strAt (2 ), Malloc);
872899 }
873900 break ;
@@ -886,28 +913,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
886913
887914 // using struct in a function call..
888915 else if (Token::Match (tok3, " %name% (" )) {
889- // Calling non-function / function that doesn't deallocate?
890- if (CheckMemoryLeakInFunction::test_white_list (tok3->str (), mSettings , mTokenizer ->isCPP ()))
891- continue ;
892-
893- // Check if the struct is used..
894- bool deallocated = false ;
895- const Token* const end4 = tok3->linkAt (1 );
896- for (const Token *tok4 = tok3; tok4 != end4; tok4 = tok4->next ()) {
897- if (Token::Match (tok4, " [(,] &| %varid% [,)]" , structid)) {
898- /* * @todo check if the function deallocates the memory */
899- deallocated = true ;
900- break ;
901- }
902-
903- if (Token::Match (tok4, " [(,] &| %varid% . %name% [,)]" , structid)) {
904- /* * @todo check if the function deallocates the memory */
905- deallocated = true ;
906- break ;
907- }
908- }
909-
910- if (deallocated)
916+ if (deallocInFunction (tok3, structid))
911917 break ;
912918 }
913919 }
0 commit comments