Skip to content

Commit f9eeab0

Browse files
Update testautovariables.cpp
1 parent c538bbd commit f9eeab0

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

test/testautovariables.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class TestAutoVariables : public TestFixture {
169169
TEST_CASE(deadPointer);
170170
TEST_CASE(splitNamespaceAuto); // crash #10473
171171
TEST_CASE(incompleteTypeArray);
172+
TEST_CASE(stlCstr);
172173
}
173174

174175

@@ -2923,6 +2924,12 @@ class TestAutoVariables : public TestFixture {
29232924
" return it;\n"
29242925
"}\n");
29252926
ASSERT_EQUALS("[test.cpp:3:44] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
2927+
2928+
check("void f(std::vector<int*>& m) {\n"
2929+
" int x;\n"
2930+
" m.push_back(&x);\n"
2931+
"}\n");
2932+
ASSERT_EQUALS("[test.cpp:3:17] -> [test.cpp:3:17] -> [test.cpp:2:9] -> [test.cpp:3:5]: (error) Non-local variable 'm' will use object that points to local variable 'x'. [danglingLifetime]\n", errout_str());
29262933
}
29272934

29282935
void danglingLifetimeContainerView()
@@ -4840,6 +4847,131 @@ class TestAutoVariables : public TestFixture {
48404847
"}\n");
48414848
ASSERT_EQUALS("", errout_str()); // don't crash
48424849
}
4850+
4851+
4852+
void stlCstr() {
4853+
4854+
check("void f() {\n"
4855+
" std::string errmsg;\n"
4856+
" throw errmsg.c_str();\n"
4857+
"}");
4858+
ASSERT_EQUALS("[test.cpp:3:23] -> [test.cpp:2:17] -> [test.cpp:3:23]: (error) Returning pointer to local variable 'errmsg' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4859+
4860+
check("const char *get_msg() {\n"
4861+
" std::string errmsg;\n"
4862+
" return errmsg.c_str();\n"
4863+
"}");
4864+
ASSERT_EQUALS("[test.cpp:3:24] -> [test.cpp:2:17] -> [test.cpp:3:24]: (error) Returning pointer to local variable 'errmsg' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4865+
4866+
check("const char *get_msg() {\n"
4867+
" std::ostringstream errmsg;\n"
4868+
" return errmsg.str().c_str();\n"
4869+
"}");
4870+
ASSERT_EQUALS("[test.cpp:3:30] -> [test.cpp:3:30]: (error) Returning object that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4871+
4872+
check("const char *get_msg() {\n"
4873+
" std::string errmsg;\n"
4874+
" return std::string(\"ERROR: \" + errmsg).c_str();\n"
4875+
"}");
4876+
ASSERT_EQUALS("[test.cpp:3:49] -> [test.cpp:3:49]: (error) Returning object that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4877+
4878+
check("const char *get_msg() {\n"
4879+
" std::string errmsg;\n"
4880+
" return (\"ERROR: \" + errmsg).c_str();\n"
4881+
"}");
4882+
ASSERT_EQUALS("[test.cpp:3:38] -> [test.cpp:3:38]: (error) Returning object that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4883+
4884+
check("const char *get_msg() {\n"
4885+
" std::string errmsg;\n"
4886+
" return (\"ERROR: \" + std::string(\"crash me\")).c_str();\n"
4887+
"}");
4888+
ASSERT_EQUALS("[test.cpp:3:55] -> [test.cpp:3:55]: (error) Returning object that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4889+
4890+
check("void f() {\n"
4891+
" std::ostringstream errmsg;\n"
4892+
" const char *c = errmsg.str().c_str();\n"
4893+
" (void)c;\n"
4894+
"}");
4895+
ASSERT_EQUALS("[test.cpp:3:39] -> [test.cpp:3:31] -> [test.cpp:4:11]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n", errout_str());
4896+
4897+
check("std::string f();\n"
4898+
"\n"
4899+
"void foo() {\n"
4900+
" const char *c = f().c_str();\n"
4901+
" (void)c;\n"
4902+
"}");
4903+
ASSERT_EQUALS("[test.cpp:4:30] -> [test.cpp:4:22] -> [test.cpp:5:11]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n", errout_str());
4904+
4905+
check("class Foo {\n"
4906+
" const char *f();\n"
4907+
"};\n"
4908+
"const char *Foo::f() {\n"
4909+
" std::string s;\n"
4910+
" return s.c_str();\n"
4911+
"}");
4912+
ASSERT_EQUALS("[test.cpp:6:19] -> [test.cpp:5:17] -> [test.cpp:6:19]: (error) Returning pointer to local variable 's' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4913+
4914+
check("class Foo {\n"
4915+
" std::string GetVal() const;\n"
4916+
"};\n"
4917+
"const char *f() {\n"
4918+
" Foo f;\n"
4919+
" return f.GetVal().c_str();\n"
4920+
"}");
4921+
ASSERT_EQUALS("[test.cpp:6:28] -> [test.cpp:6:28]: (error) Returning pointer that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4922+
4923+
check("std::string hello()\n"
4924+
"{\n"
4925+
" return \"hello\";\n"
4926+
"}\n"
4927+
"\n"
4928+
"const char *f()\n"
4929+
"{\n"
4930+
" return hello().c_str();\n"
4931+
"}");
4932+
ASSERT_EQUALS("[test.cpp:8:25] -> [test.cpp:8:25]: (error) Returning pointer that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4933+
4934+
check("class Fred {\n"
4935+
" std::string hello();\n"
4936+
" const char *f();\n"
4937+
"};\n"
4938+
"std::string Fred::hello()\n"
4939+
"{\n"
4940+
" return \"hello\";\n"
4941+
"}\n"
4942+
"const char *Fred::f()\n"
4943+
"{\n"
4944+
" return hello().c_str();\n"
4945+
"}");
4946+
ASSERT_EQUALS("[test.cpp:11:25] -> [test.cpp:11:25]: (error) Returning pointer that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4947+
4948+
check("struct InternalMapInfo {\n"
4949+
" std::string author;\n"
4950+
"};\n"
4951+
"const char* GetMapAuthor(int index) {\n"
4952+
" const InternalMapInfo mapInfo = internal_getMapInfo;\n"
4953+
" return mapInfo.author.c_str();\n"
4954+
"}");
4955+
ASSERT_EQUALS("[test.cpp:6:32] -> [test.cpp:6:32]: (error) Returning pointer that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4956+
4957+
check("struct S {\n" // #7930
4958+
" std::string data;\n"
4959+
"};\n"
4960+
"const char* test() {\n"
4961+
" S s;\n"
4962+
" std::string &ref = s.data;\n"
4963+
" return ref.c_str();\n"
4964+
"}");
4965+
ASSERT_EQUALS("[test.cpp:6:22] -> [test.cpp:7:21] -> [test.cpp:7:21]: (error) Returning pointer that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4966+
4967+
check("struct S {\n" //#9161
4968+
" const char* f() const noexcept {\n"
4969+
" return (\"\" + m).c_str();\n"
4970+
" }\n"
4971+
" std::string m;\n"
4972+
"};\n");
4973+
ASSERT_EQUALS("[test.cpp:3:30] -> [test.cpp:3:30]: (error) Returning object that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
4974+
}
48434975

48444976
};
48454977

0 commit comments

Comments
 (0)