From 1c84dc814c0b398e1e0e7f55c5590d8332998eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 27 Jan 2010 19:16:32 +0100 Subject: [PATCH] Auto variables: Improved handling of temporaries --- lib/checkautovariables.cpp | 34 ++++++++++++++++++++++++++++++++++ lib/checkautovariables.h | 13 +++++++++++-- test/testautovariables.cpp | 6 ++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 110c32e80..fc27070a5 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -307,6 +307,16 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok) } + +// return temporary? +bool CheckAutoVariables::returnTemporary(const Token *tok) const +{ + if (!Token::Match(tok, "return %var% (")) + return false; + return bool(0 != Token::findmatch(_tokenizer->tokens(), ("std :: string " + tok->next()->str() + " (").c_str())); +} + + void CheckAutoVariables::returnReference() { // locate function that returns a reference.. @@ -381,6 +391,13 @@ void CheckAutoVariables::returnReference() errorReturnReference(tok2); } } + + // return reference to temporary.. + else if (returnTemporary(tok2)) + { + // report error.. + errorReturnTempReference(tok2); + } } } } @@ -392,6 +409,11 @@ void CheckAutoVariables::errorReturnReference(const Token *tok) reportError(tok, Severity::error, "returnReference", "Returning reference to auto variable"); } +void CheckAutoVariables::errorReturnTempReference(const Token *tok) +{ + reportError(tok, Severity::error, "returnTempReference", "Returning reference to temporary"); +} + // Return c_str void CheckAutoVariables::returncstr() @@ -465,6 +487,13 @@ void CheckAutoVariables::returncstr() errorReturnAutocstr(tok2); } } + + // return pointer to temporary.. + else if (returnTemporary(tok2)) + { + // report error.. + errorReturnTempPointer(tok2); + } } } } @@ -476,5 +505,10 @@ void CheckAutoVariables::errorReturnAutocstr(const Token *tok) reportError(tok, Severity::error, "returnAutocstr", "Returning pointer to auto variable"); } +void CheckAutoVariables::errorReturnTempPointer(const Token *tok) +{ + reportError(tok, Severity::error, "returnTempPointer", "Returning pointer to temporary"); +} + diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index c63cfdf93..e6baa9102 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -72,19 +72,28 @@ private: void addVD(unsigned int varId); void addVDA(unsigned int varId); - + /** + * Returning a temporary object? + * @param tok pointing at the "return" token + * @return true if a temporary object is returned + */ + bool returnTemporary(const Token *tok) const; void errorReturnPointerToLocalArray(const Token *tok); void errorAutoVariableAssignment(const Token *tok); void errorReturnReference(const Token *tok); + void errorReturnTempReference(const Token *tok); void errorReturnAutocstr(const Token *tok); + void errorReturnTempPointer(const Token *tok); void getErrorMessages() { errorAutoVariableAssignment(0); errorReturnPointerToLocalArray(0); errorReturnReference(0); + errorReturnTempReference(0); errorReturnAutocstr(0); + errorReturnTempPointer(0); } std::string name() const @@ -96,7 +105,7 @@ private: { return "A pointer to a variable is only valid as long as the variable is in scope.\n" "Check:\n" - "* returning a pointer to auto variable\n" + "* returning a pointer to auto or temporary variable\n" "* assigning address of an variable to an effective parameter of a function\n" "* returning reference to local/temporary variable\n"; } diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index f402eadc6..ad34a641d 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -201,8 +201,7 @@ private: "{\n" " return hello();\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Returning reference to temporary\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) Returning reference to temporary\n", errout.str()); } void returncstr() @@ -223,8 +222,7 @@ private: "{\n" " return hello().c_str();\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Returning pointer to temporary\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) Returning pointer to temporary\n", errout.str()); } };