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