1 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected       %s
2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected       %s
3 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify=expected,cxx11 %s
4 
5 int* ret_local() {
6   int x = 1;
7   return &x; // expected-warning {{address of stack memory}}
8 }
9 
10 int* ret_local_array() {
11   int x[10];
12   return x; // expected-warning {{address of stack memory}}
13 }
14 
15 int* ret_local_array_element(int i) {
16   int x[10];
17   return &x[i]; // expected-warning {{address of stack memory}}
18 }
19 
20 int *ret_local_array_element_reversed(int i) {
21   int x[10];
22   return &i[x]; // expected-warning {{address of stack memory}}
23 }
24 
25 int* ret_local_array_element_const_index() {
26   int x[10];
27   return &x[2];  // expected-warning {{address of stack memory}}
28 }
29 
30 int& ret_local_ref() {
31   int x = 1;
32   return x;  // expected-warning {{reference to stack memory}}
33 }
34 
35 int* ret_local_addrOf() {
36   int x = 1;
37   return &*&x; // expected-warning {{address of stack memory}}
38 }
39 
40 int* ret_local_addrOf_paren() {
41   int x = 1;
42   return (&(*(&x))); // expected-warning {{address of stack memory}}
43 }
44 
45 int* ret_local_addrOf_ptr_arith() {
46   int x = 1;
47   return &*(&x+1); // expected-warning {{address of stack memory}}
48 }
49 
50 int* ret_local_addrOf_ptr_arith2() {
51   int x = 1;
52   return &*(&x+1); // expected-warning {{address of stack memory}}
53 }
54 
55 int* ret_local_field() {
56   struct { int x; } a;
57   return &a.x; // expected-warning {{address of stack memory}}
58 }
59 
60 int& ret_local_field_ref() {
61   struct { int x; } a;
62   return a.x; // expected-warning {{reference to stack memory}}
63 }
64 
65 int* ret_conditional(bool cond) {
66   int x = 1;
67   int y = 2;
68   return cond ? &x // expected-warning {{address of stack memory associated with local variable 'x' returned}}
69               : &y; // expected-warning {{address of stack memory associated with local variable 'y' returned}}
70 }
71 
72 int* ret_conditional_rhs(int *x, bool cond) {
73   int y = 1;
74   return cond ? x : &y;  // expected-warning {{address of stack memory}}
75 }
76 
77 void* ret_c_cast() {
78   int x = 1;
79   return (void*) &x;  // expected-warning {{address of stack memory}}
80 }
81 
82 int* ret_static_var() {
83   static int x = 1;
84   return &x;  // no warning.
85 }
86 
87 int z = 1;
88 
89 int* ret_global() {
90   return &z;  // no warning.
91 }
92 
93 int* ret_parameter(int x) {
94   return &x;  // expected-warning {{address of stack memory}}
95 }
96 
97 
98 void* ret_cpp_static_cast(short x) {
99   return static_cast<void*>(&x); // expected-warning {{address of stack memory}}
100 }
101 
102 int* ret_cpp_reinterpret_cast(double x) {
103   return reinterpret_cast<int*>(&x); // expected-warning {{address of stack me}}
104 }
105 
106 int* ret_cpp_reinterpret_cast_no_warning(long x) {
107   return reinterpret_cast<int*>(x); // no-warning
108 }
109 
110 int* ret_cpp_const_cast(const int x) {
111   return const_cast<int*>(&x);  // expected-warning {{address of stack memory}}
112 }
113 
114 struct A { virtual ~A(); }; struct B : A {};
115 A* ret_cpp_dynamic_cast(B b) {
116   return dynamic_cast<A*>(&b); // expected-warning {{address of stack memory}}
117 }
118 
119 // PR 7999 - handle the case where a field is itself a reference.
120 template <typename T> struct PR7999 {
121   PR7999(T& t) : value(t) {}
122   T& value;
123 };
124 
125 struct PR7999_X {};
126 
127 PR7999_X& PR7999_f(PR7999<PR7999_X> s) { return s.value; } // no-warning
128 void test_PR7999(PR7999_X& x) { (void)PR7999_f(x); } // no-warning
129 
130 // PR 8774: Don't try to evaluate parameters with default arguments like
131 // variables with an initializer, especially in templates where the default
132 // argument may not be an expression (yet).
133 namespace PR8774 {
134   template <typename U> struct B { };
135   template <typename V> V f(typename B<V>::type const &v = B<V>::value()) {
136     return v;
137   }
138   template <> struct B<const char *> {
139     typedef const char *type;
140     static const char *value();
141   };
142   void g() {
143     const char *t;
144     f<const char*>(t);
145   }
146 }
147 
148 // Don't warn about returning a local variable from a surrounding function if
149 // we're within a lambda-expression.
150 void ret_from_lambda() {
151   int a;
152   int &b = a;
153   (void) [&]() -> int& { return a; };
154   (void) [&]() -> int& { return b; };
155   (void) [=]() mutable -> int& { return a; };
156   (void) [=]() mutable -> int& { return b; };
157   (void) [&]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
158   (void) [=]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
159   (void) [&]() -> int& { int &a = b; return a; };
160   (void) [=]() mutable -> int& { int &a = b; return a; };
161 
162   (void) [] {
163     int a;
164     return [&] { // expected-warning {{address of stack memory associated with local variable 'a' returned}}
165       return a; // expected-note {{implicitly captured by reference due to use here}}
166     };
167   };
168   (void) [] {
169     int a;
170     return [&a] {}; // expected-warning {{address of stack memory associated with local variable 'a' returned}} expected-note {{captured by reference here}}
171   };
172   (void) [] {
173     int a;
174     return [=] {
175       return a;
176     };
177   };
178   (void) [] {
179     int a;
180     return [a] {};
181   };
182   (void) [] {
183     int a;
184     // cxx11-warning@+1 {{C++14}}
185     return [&b = a] {}; // expected-warning {{address of stack memory associated with local variable 'a' returned}} expected-note {{captured by reference via initialization of lambda capture 'b'}}
186   };
187   (void) [] {
188     int a;
189     // cxx11-warning@+1 {{C++14}}
190     return [b = &a] {}; // expected-warning {{address of stack memory associated with local variable 'a' returned}} expected-note {{captured via initialization of lambda capture 'b'}}
191   };
192 }
193 
194 struct HoldsPointer { int *p; };
195 
196 HoldsPointer ret_via_member_1() {
197   int n;
198   return {&n}; // expected-warning {{address of stack memory associated with local variable 'n' returned}}
199 }
200 HoldsPointer ret_via_member_2() {
201   int n;
202   return HoldsPointer(HoldsPointer{&n}); // cxx11-warning {{address of stack memory associated with local variable 'n' returned}}
203 }
204 // FIXME: We could diagnose this too.
205 HoldsPointer ret_via_member_3() {
206   int n;
207   const HoldsPointer hp = HoldsPointer{&n};
208   return hp;
209 }
210 
211 namespace mem_ptr {
212   struct X {};
213   int X::*f();
214   int &r(X *p) { return p->*f(); }
215 }
216 
217 namespace PR47861 {
218   struct A {
219     A(int i);
220     A &operator+=(int i);
221   };
222   A const &b = A(5) += 5; // expected-warning {{temporary bound to local reference 'b' will be destroyed at the end of the full-expression}}
223 }
224