From aeb573d5296920461782dac177cbad84e0a8ebae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 4 Feb 2009 18:49:19 +0000 Subject: [PATCH] returning pointer to local array --- src/checkother.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++ src/checkother.h | 3 +++ src/errormessage.h | 9 ++++++++ test/testother.cpp | 29 +++++++++++++++++++++++++ tools/errmsg.cpp | 1 + 5 files changed, 95 insertions(+) diff --git a/src/checkother.cpp b/src/checkother.cpp index 34f1395cd..33430b139 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -21,6 +21,7 @@ //--------------------------------------------------------------------------- #include "checkother.h" #include "errormessage.h" +#include #include #include #include @@ -813,3 +814,55 @@ void CheckOther::strPlusChar() } } } + + + + + +void CheckOther::returnPointerToStackData() +{ + bool infunc = false; + int indentlevel = 0; + std::list arrayVar; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (!infunc && Token::simpleMatch(tok, ") {")) + { + infunc = true; + indentlevel = 0; + arrayVar.clear(); + } + + if (infunc) + { + if (tok->str() == "{") + ++indentlevel; + else if (tok->str() == "}") + { + --indentlevel; + if (indentlevel <= 0) + infunc = false; + continue; + } + + // Declaring a local array.. + if (Token::Match(tok, "[;{}] %type% %var% [")) + { + arrayVar.push_back(tok->tokAt(2)->varId()); + } + + // Return pointer to local array variable.. + if (Token::Match(tok, "return %var% ;")) + { + unsigned int varid = tok->next()->varId(); + if (varid > 0 && std::find(arrayVar.begin(), arrayVar.end(), varid) != arrayVar.end()) + ErrorMessage::returnLocalVariable(_errorLogger, _tokenizer, tok); + } + } + + // Declaring array variable.. + + + } +} + diff --git a/src/checkother.h b/src/checkother.h index a365b041a..d2e4b0206 100644 --- a/src/checkother.h +++ b/src/checkother.h @@ -65,6 +65,9 @@ public: /** str plus char */ void strPlusChar(); + /** Returning pointer to local data */ + void returnPointerToStackData(); + #ifndef UNIT_TESTING private: #endif diff --git a/src/errormessage.h b/src/errormessage.h index 402deb78c..b8cc5fa75 100644 --- a/src/errormessage.h +++ b/src/errormessage.h @@ -332,5 +332,14 @@ public: return true; } + static void returnLocalVariable(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location) + { + _writemsg(logger, tokenizer, Location, "always", "Returning pointer to local array variable", "returnLocalVariable"); + } + static bool returnLocalVariable() + { + return true; + } + }; #endif diff --git a/test/testother.cpp b/test/testother.cpp index c7fc79f20..1aeb59523 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -48,6 +48,8 @@ private: TEST_CASE(strPlusChar1); // "/usr" + '/' TEST_CASE(strPlusChar2); // "/usr" + ch TEST_CASE(strPlusChar3); // ok: path + "/sub" + '/' + + TEST_CASE(returnLocalVariable1); } void check(const char code[]) @@ -230,6 +232,33 @@ private: ASSERT_EQUALS(std::string(""), errout.str()); } + + + void retVar(const char code[]) + { + // Tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.setVarId(); + + // Clear the error buffer.. + errout.str(""); + + // Check for redundant code.. + CheckOther checkOther(&tokenizer, Settings(), this); + checkOther.returnPointerToStackData(); + } + + void returnLocalVariable1() + { + retVar("char *foo()\n" + "{\n" + " char str[100] = {0};\n" + " return str;\n" + "\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: (always) Returning pointer to local array variable\n"), errout.str()); + } }; REGISTER_TEST(TestOther) diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp index 716df2502..b36636068 100644 --- a/tools/errmsg.cpp +++ b/tools/errmsg.cpp @@ -102,6 +102,7 @@ int main() err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname")); err.push_back(Message("conditionAlwaysTrueFalse", Message::style, "Condition is always %1", "truefalse")); err.push_back(Message("strPlusChar", Message::always, "Unusual pointer arithmetic")); + err.push_back(Message("returnLocalVariable", Message::always, "Returning pointer to local array variable")); // Generate code.. std::cout << "Generate code.." << std::endl;