1 #include <mozilla/StaticAnalysisFunctions.h>
5 #define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
7 // Ensure that warnings about returning stack addresses of local variables are
8 // errors, so our `expected-error` annotations below work correctly.
9 #pragma GCC diagnostic error "-Wreturn-stack-address"
11 struct RefCountedBase
{
19 MOZ_IMPLICIT
SmartPtr(T
*);
21 T
* operator->() const;
24 struct R
: RefCountedBase
{
40 take([&](SmartPtr
<R
> argsp
) {
52 take([&](SmartPtr
<R
> argsp
) {
64 take([=](SmartPtr
<R
> argsp
) {
76 take([=](SmartPtr
<R
> argsp
) {
82 take([ptr
](R
* argptr
) {
88 take([sp
](SmartPtr
<R
> argsp
) {
94 take([ptr
](R
* argptr
) {
100 take([sp
](SmartPtr
<R
> argsp
) {
106 take([&ptr
](R
* argptr
) {
112 take([&sp
](SmartPtr
<R
> argsp
) {
118 take([&ptr
](R
* argptr
) {
124 take([&sp
](SmartPtr
<R
> argsp
) {
135 std::function
<void(R
*)>([&](R
* argptr
) {
141 std::function
<void(SmartPtr
<R
>)>([&](SmartPtr
<R
> argsp
) {
147 std::function
<void(R
*)>([&](R
* argptr
) {
153 std::function
<void(SmartPtr
<R
>)>([&](SmartPtr
<R
> argsp
) {
159 std::function
<void(R
*)>([=](R
* argptr
) {
161 ptr
->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
165 std::function
<void(SmartPtr
<R
>)>([=](SmartPtr
<R
> argsp
) {
171 std::function
<void(R
*)>([=](R
* argptr
) {
173 take(ptr
); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
177 std::function
<void(SmartPtr
<R
>)>([=](SmartPtr
<R
> argsp
) {
183 std::function
<void(R
*)>([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
189 std::function
<void(SmartPtr
<R
>)>([sp
](SmartPtr
<R
> argsp
) {
195 std::function
<void(R
*)>([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
201 std::function
<void(SmartPtr
<R
>)>([sp
](SmartPtr
<R
> argsp
) {
207 std::function
<void(R
*)>([&ptr
](R
* argptr
) {
213 std::function
<void(SmartPtr
<R
>)>([&sp
](SmartPtr
<R
> argsp
) {
219 std::function
<void(R
*)>([&ptr
](R
* argptr
) {
225 std::function
<void(SmartPtr
<R
>)>([&sp
](SmartPtr
<R
> argsp
) {
233 // These tests would check c++14 deduced return types, if they were supported in
234 // our codebase. They are being kept here for convenience in the future if we do
235 // add support for c++14 deduced return types
240 return ([&](R
* argptr
) {
250 return ([&](SmartPtr
<R
> argsp
) {
260 return ([&](R
* argptr
) {
270 return ([&](SmartPtr
<R
> argsp
) {
280 return ([=](R
* argptr
) {
282 ptr
->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
290 return ([=](SmartPtr
<R
> argsp
) {
300 return ([=](R
* argptr
) {
302 take(ptr
); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
310 return ([=](SmartPtr
<R
> argsp
) {
320 return ([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
330 return ([sp
](SmartPtr
<R
> argsp
) {
340 return ([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
350 return ([sp
](SmartPtr
<R
> argsp
) {
360 return ([&ptr
](R
* argptr
) {
370 return ([&sp
](SmartPtr
<R
> argsp
) {
380 return ([&ptr
](R
* argptr
) {
390 return ([&sp
](SmartPtr
<R
> argsp
) {
403 return ([&](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}}
405 #if __clang_major__ >= 12
406 ptr
->method(); // expected-note{{implicitly captured by reference due to use here}}
417 return ([&](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}}
419 #if __clang_major__ >= 12
420 sp
->method(); // expected-note{{implicitly captured by reference due to use here}}
431 return ([&](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}}
433 #if __clang_major__ >= 12
434 take(ptr
); // expected-note{{implicitly captured by reference due to use here}}
445 return ([&](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}}
447 #if __clang_major__ >= 12
448 take(sp
); // expected-note{{implicitly captured by reference due to use here}}
459 return ([=](R
* argptr
) {
461 ptr
->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
469 return ([=](SmartPtr
<R
> argsp
) {
479 return ([=](R
* argptr
) {
481 take(ptr
); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
489 return ([=](SmartPtr
<R
> argsp
) {
499 return ([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
509 return ([sp
](SmartPtr
<R
> argsp
) {
519 return ([ptr
](R
* argptr
) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
529 return ([sp
](SmartPtr
<R
> argsp
) {
539 #if __clang_major__ >= 12
540 return ([&ptr
](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}} expected-note{{captured by reference here}}
547 return ([&ptr
](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}}
558 #if __clang_major__ >= 12
559 return ([&sp
](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}} expected-note{{captured by reference here}}
566 return ([&sp
](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}}
577 #if __clang_major__ >= 12
578 return ([&ptr
](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}} expected-note{{captured by reference here}}
585 return ([&ptr
](R
* argptr
) { // expected-error{{address of stack memory associated with local variable 'ptr' returned}}
596 #if __clang_major__ >= 12
597 return ([&sp
](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}} expected-note{{captured by reference here}}
604 return ([&sp
](SmartPtr
<R
> argsp
) { // expected-error{{address of stack memory associated with local variable 'sp' returned}}
616 SmartPtr
<R
> self
= this;
617 std::function
<void()>([&]() {
620 std::function
<void()>([&]() {
621 self
->privateMethod();
623 std::function
<void()>([&]() {
626 std::function
<void()>([&]() {
627 this->privateMethod();
629 std::function
<void()>([=]() {
632 std::function
<void()>([=]() {
633 self
->privateMethod();
635 std::function
<void()>([=]() {
636 this->method(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
638 std::function
<void()>([=]() {
639 this->privateMethod(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
641 std::function
<void()>([self
]() {
644 std::function
<void()>([self
]() {
645 self
->privateMethod();
647 std::function
<void()>([this]() {
648 this->method(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
650 std::function
<void()>([this]() {
651 this->privateMethod(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
653 std::function
<void()>([this]() {
654 method(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
656 std::function
<void()>([this]() {
657 privateMethod(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
659 std::function
<void()>([=]() {
660 method(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
662 std::function
<void()>([=]() {
663 privateMethod(); // expected-error{{Refcounted variable 'this' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
665 std::function
<void()>([&]() {
668 std::function
<void()>([&]() {
672 std::function
<void()>(
673 [instance
= MOZ_KnownLive(this)]() { instance
->privateMethod(); });
675 // It should be OK to go through `this` if we have captured a reference to it.
676 std::function
<void()>([this, self
]() {
678 this->privateMethod();