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