- Notifications
You must be signed in to change notification settings - Fork 15.3k
[clang-tidy] Fix smart pointers handling in bugprone-use-after-move #94869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -200,7 +200,8 @@ An exception to this are objects of type ``std::unique_ptr``, | |
| (objects of these classes are guaranteed to be empty after they have been moved | ||
| from). Therefore, an object of these classes will only be considered to be used | ||
| if it is dereferenced, i.e. if ``operator*``, ``operator->`` or ``operator[]`` | ||
| (in the case of ``std::unique_ptr<T []>``) is called on it. | ||
| (in the case of ``std::unique_ptr<T []>``) is called on it. This behavior can be | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part of the documentation still reads as if this is the default behavior, but in fact it isn't. Can you rephrase this to make this clear that this is optional (non-default) behavior that is activated by setting the | ||
| overridden with the option :option:`AllowMovedSmartPtrUse`. | ||
| | ||
| If multiple uses occur after a move, only the first of these is flagged. | ||
| | ||
| | @@ -250,3 +251,14 @@ For example, if an additional member variable is added to ``S``, it is easy to | |
| forget to add the reinitialization for this additional member. Instead, it is | ||
| safer to assign to the entire struct in one go, and this will also avoid the | ||
| use-after-move warning. | ||
| | ||
| Options | ||
| ------- | ||
| | ||
| .. option:: AllowMovedSmartPtrUse | ||
| | ||
| If this option is set to `true`, the check will not warn about uses of | ||
| ``std::unique_ptr``, ``std::shared_ptr`` that are not dereferences. This | ||
| can be useful if you are using these smart pointers in a way that is not | ||
| idiomatic, but that you know is safe. Default is `false`. | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "This can be useful if you are using these smart pointers in a way that is not idiomatic, but that you know is safe." I think "not idiomatic" is too strong -- I would say this is a question of style. Maybe just leave out this entire sentence (i.e. describe only the behavior)? | ||
| | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-use-after-move %t -- \ | ||
| // RUN: -config="{CheckOptions: {bugprone-use-after-move.AllowMovedSmartPtrUse: false}}" -- -fno-delayed-template-parsing -I %S/../modernize/Inputs/smart-ptr/ | ||
| | ||
| #include "unique_ptr.h" | ||
| | ||
| namespace PR90174 { | ||
| | ||
| struct A {}; | ||
| | ||
| struct SinkA { | ||
| SinkA(std::unique_ptr<A>); | ||
| }; | ||
| | ||
| class ClassB { | ||
| ClassB(std::unique_ptr<A> aaa) : aa(std::move(aaa)) { | ||
| a = std::make_unique<SinkA>(std::move(aaa)); | ||
| // CHECK-MESSAGES: [[@LINE-1]]:43: warning: 'aaa' used after it was moved | ||
| // CHECK-MESSAGES: [[@LINE-3]]:36: note: move occurred here | ||
| } | ||
| std::unique_ptr<A> aa; | ||
| std::unique_ptr<SinkA> a; | ||
| }; | ||
| | ||
| void s(const std::unique_ptr<A> &); | ||
| | ||
| template <typename T, typename... Args> auto my_make_unique(Args &&...args) { | ||
| return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||
| } | ||
| | ||
| void natively(std::unique_ptr<A> x) { | ||
| std::unique_ptr<A> tmp = std::move(x); | ||
| std::unique_ptr<SinkA> y2{new SinkA(std::move(x))}; | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason (here and possibly also below) that I.e. why not simply do SinkA sink(std::move(x));since the behavior we're interested in is what happens when we move (Also nit: I'm not clear on the reason for the | ||
| // CHECK-MESSAGES: [[@LINE-1]]:49: warning: 'x' used after it was moved | ||
| // CHECK-MESSAGES: [[@LINE-3]]:28: note: move occurred here | ||
| } | ||
| | ||
| void viaStdMakeUnique(std::unique_ptr<A> x) { | ||
| std::unique_ptr<A> tmp = std::move(x); | ||
| std::unique_ptr<SinkA> y2 = | ||
| std::make_unique<SinkA>(std::move(x)); | ||
| // CHECK-MESSAGES: [[@LINE-1]]:41: warning: 'x' used after it was moved | ||
| // CHECK-MESSAGES: [[@LINE-4]]:28: note: move occurred here | ||
| } | ||
| | ||
| void viaMyMakeUnique(std::unique_ptr<A> x) { | ||
| std::unique_ptr<A> tmp = std::move(x); | ||
| std::unique_ptr<SinkA> y2 = my_make_unique<SinkA>(std::move(x)); | ||
| // CHECK-MESSAGES: [[@LINE-1]]:63: warning: 'x' used after it was moved | ||
| // CHECK-MESSAGES: [[@LINE-3]]:28: note: move occurred here | ||
| } | ||
| | ||
| void viaMyMakeUnique2(std::unique_ptr<A> x) { | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this test called | ||
| std::unique_ptr<A> tmp = std::move(x); | ||
| s(x); | ||
| // CHECK-MESSAGES: [[@LINE-1]]:5: warning: 'x' used after it was moved | ||
| // CHECK-MESSAGES: [[@LINE-3]]:28: note: move occurred here | ||
| } | ||
| | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
->