File tree Expand file tree Collapse file tree 3 files changed +74
-1
lines changed
lib/StaticAnalyzer/Checkers Expand file tree Collapse file tree 3 files changed +74
-1
lines changed Original file line number Diff line number Diff line change @@ -274,7 +274,13 @@ class FindStackRegionsSymbolVisitor final : public SymbolVisitor {
274274 void SaveIfEscapes (const MemRegion *MR) {
275275 const StackSpaceRegion *SSR =
276276 MR->getMemorySpace ()->getAs <StackSpaceRegion>();
277- if (SSR && SSR->getStackFrame () == PoppedStackFrame)
277+
278+ if (!SSR)
279+ return ;
280+
281+ const StackFrameContext *CapturedSFC = SSR->getStackFrame ();
282+ if (CapturedSFC == PoppedStackFrame ||
283+ PoppedStackFrame->isParentOf (CapturedSFC))
278284 EscapingStackRegions.push_back (MR);
279285 }
280286
Original file line number Diff line number Diff line change @@ -982,6 +982,51 @@ int& ret_local_field_ref() {
982982}
983983} // namespace return_address_of_true_positives
984984
985+ namespace return_from_child_block_scope {
986+ struct S {
987+ int *p;
988+ };
989+
990+ S return_child_stack_context () {
991+ S s;
992+ {
993+ int a = 1 ;
994+ s = (S){ &a };
995+ }
996+ return s; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}}
997+ }
998+
999+ S return_child_stack_context_field () {
1000+ S s;
1001+ {
1002+ int a = 1 ;
1003+ s.p = &a;
1004+ }
1005+ return s; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}}
1006+ }
1007+
1008+ // The below are reproducers from Issue #123459
1009+ template <typename V>
1010+ struct T {
1011+ V* q{};
1012+ T () = default ;
1013+ T (T&& rhs) { q = rhs.q ; rhs.q = nullptr ;}
1014+ T& operator =(T&& rhs) { q = rhs.q ; rhs.q = nullptr ;}
1015+ void push_back (const V& v) { if (q == nullptr ) q = new V (v); }
1016+ ~T () { delete q; }
1017+ };
1018+
1019+ T<S> f () {
1020+ T<S> t;
1021+ {
1022+ int a = 1 ;
1023+ t.push_back ({ &a });
1024+ }
1025+ return t; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}}
1026+ }
1027+
1028+ } // namespace return_from_child_block_scope
1029+
9851030namespace true_negatives_return_expressions {
9861031struct Container { int *x; };
9871032
Original file line number Diff line number Diff line change @@ -68,3 +68,25 @@ int *g_no_lifetime_bound() {
6868 int i = 0 ;
6969 return f_no_lifetime_bound (& i ); // no-warning
7070}
71+
72+ struct child_stack_context_s {
73+ int * p ;
74+ };
75+
76+ struct child_stack_context_s return_child_stack_context () {
77+ struct child_stack_context_s s ;
78+ {
79+ int a = 1 ;
80+ s = (struct child_stack_context_s ){ & a };
81+ }
82+ return s ; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}}
83+ }
84+
85+ struct child_stack_context_s return_child_stack_context_field () {
86+ struct child_stack_context_s s ;
87+ {
88+ int a = 1 ;
89+ s .p = & a ;
90+ }
91+ return s ; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}}
92+ }
You can’t perform that action at this time.
0 commit comments