From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../tests/TestRefCountedThisInsideConstructor.cpp | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 build/clang-plugin/tests/TestRefCountedThisInsideConstructor.cpp (limited to 'build/clang-plugin/tests/TestRefCountedThisInsideConstructor.cpp') diff --git a/build/clang-plugin/tests/TestRefCountedThisInsideConstructor.cpp b/build/clang-plugin/tests/TestRefCountedThisInsideConstructor.cpp new file mode 100644 index 0000000000..a6684e3812 --- /dev/null +++ b/build/clang-plugin/tests/TestRefCountedThisInsideConstructor.cpp @@ -0,0 +1,76 @@ +#include + +#include + +struct RefCountedBase { + void AddRef(); + void Release(); +}; + +struct Bar; + +struct Foo : RefCountedBase { + void foo(); +}; + +struct Bar : RefCountedBase { + Bar() { + RefPtr self = this; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + auto self2 = RefPtr(this); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + auto self3 = RefPtr{this}; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + RefPtr self4(this); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + RefPtr self5{this}; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + [self=RefPtr{this}]{}(); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + refptr(RefPtr{this}); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + refptr(this); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + } + + explicit Bar(float f) { + // Does not match member expressions with `this` + RefPtr foo = this->mFoo; + foo->foo(); + auto foo2 = RefPtr(this->mFoo); + foo2->foo(); + auto foo3 = RefPtr{this->mFoo}; + foo3->foo(); + } + + explicit Bar(short i); + + explicit Bar(int i): mBar(this) {} // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + explicit Bar(int i, int i2): mBar(RefPtr(this)) {} // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + + void Init() { + // Does not match outside the constructor + RefPtr self = this; + auto self2 = RefPtr(this); + auto self3 = RefPtr{this}; + } + + void refptr(const RefPtr& aBar) {} + + RefPtr mFoo; + RefPtr mBar; +}; + +// Test case for non-inline constructor +Bar::Bar(short i) { + RefPtr self = this; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + auto self2 = RefPtr(this); // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + auto self3 = RefPtr{this}; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} +} + +// Same goes for any class with MOZ_IS_REFPTR (not including nsCOMPtr because SM +// doesn't have it) +template class MOZ_IS_REFPTR MyRefPtr { +public: + MOZ_IMPLICIT MyRefPtr(T *aPtr) : mPtr(aPtr) {} + T *mPtr; +}; + +class Baz : RefCountedBase { + Baz() { + MyRefPtr self = this; // expected-error {{Refcounting `this` inside the constructor is a footgun, `this` may be destructed at the end of the constructor unless there's another strong reference. Consider adding a separate Create function and do the work there.}} + (void)self; + } +}; -- cgit v1.2.3