chore: Enable clang-tidy bugprone-use-after-move check - #6476
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #6476 +/- ##
=========================================
- Coverage 79.8% 79.8% -0.0%
=========================================
Files 878 878
Lines 68026 68028 +2
Branches 7556 7555 -1
=========================================
- Hits 54309 54302 -7
- Misses 13717 13726 +9
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Enables the clang-tidy bugprone-use-after-move check and updates existing code/tests to accommodate the new diagnostic by adding targeted suppressions where moved-from state is intentionally inspected.
Changes:
- Enable
bugprone-use-after-movein.clang-tidy. - Add
// NOLINT(bugprone-use-after-move)suppressions in multiple unit tests that intentionally validate moved-from behavior. - Add a suppression (and TODO) in
SHAMap::delItemaround a moved-from pointer reset.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
.clang-tidy |
Turns on bugprone-use-after-move check. |
src/tests/libxrpl/json/Value.cpp |
Suppresses intentional moved-from inspections in JSON value tests. |
src/test/protocol/STObject_test.cpp |
Suppresses moved-from Buffer checks after move into STObject. |
src/test/jtx/Env_test.cpp |
Suppresses moved-from JTx state checks in move tests. |
src/test/core/ClosureCounter_test.cpp |
Suppresses moved-from string state check after forwarding/move. |
src/test/basics/Buffer_test.cpp |
Suppresses moved-from Buffer validation in move construction/assignment tests. |
src/libxrpl/shamap/SHAMap.cpp |
Suppresses a use-after-move warning on prevNode.reset() in delItem. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ximinez
left a comment
There was a problem hiding this comment.
I'm only flagging this as "request changes" to point out this comment: #6476 (comment)
Otherwise, this looks fine.
ximinez
left a comment
There was a problem hiding this comment.
The updates look good, but I did have an alternative suggestion below. Whether it works or not, if you make the change or not, just re-request, and I'll approve.
| { | ||
| // no children below this branch | ||
| prevNode.reset(); | ||
| XRPL_ASSERT( | ||
| not prevNode, // NOLINT(bugprone-use-after-move) | ||
| "xrpl::SHAMap::delItem : There should be no children below this branch"); | ||
| } |
There was a problem hiding this comment.
I'm looking fresh at the context around this change. It's in a loop and prevNode is reused on each iteration. I didn't notice that before. The old reset() is ensuring that prevNode is holding a nullptr for the next loop, juuuust in case the std::move doesn't do what we expect. But that upsets the linter. OTOH, the assignments below do not upset the linter. Have you tried doing a direct assignment like the ones below? prevNode = nullptr; or prevNode = intr_ptr::SharedPtr<SHAMapTreeNode>{}?
If that works, I think that would be a safer way to go. You can move or remove the assert.
There was a problem hiding this comment.
Let's try! In less critical code i would say this is redundant but it's SHAMap so I'll do anything to stay safe here 👍
There was a problem hiding this comment.
This line attracted my attention too. After reviewing reset() vs operator=(SharedIntrusive&&), the assignment is technically redundant—move semantics already guarantee prevNode.ptr_ becomes nullptr via unsafeExchange(nullptr).
That said, I'm fine keeping it for code clarity. The explicit assignment prevNode = TreeNodeType{} makes the intent obvious to readers who aren't familiar with SharedIntrusive internals, even though it performs no actual refcount operations (the null check in unsafeReleaseAndStore causes an early return).
Not a safety issue, just a style preference for defensive clarity.
There was a problem hiding this comment.
[nit] Another alternative would be to use std::exchange here:
node->setChild(
selectBranch(nodeID, id),
std::exchange(prevNode, TreeNodeType{}));This keeps the explicit reset while avoiding the moved-from state entirely, which allows
removing the // NOLINT(bugprone-use-after-move) suppression.
There was a problem hiding this comment.
Agree with your assessment and I too think that this is a good alternative. But i'm somewhat hesitant to touch SHAMap code in general so prefer to leave the ASSERT and explicit assignment at this time 👍
There was a problem hiding this comment.
@vlntb is this something you could pick in as a follow-up PR, given you're much more familiar with the SHAMap?
There was a problem hiding this comment.
Sure, it requires both SHAMap and intrusive pointers knowledge - I'm happy to do a follow-up on this, even if it is not an essential change.
vlntb
left a comment
There was a problem hiding this comment.
LGTM. Added an optional suggestion.
High Level Overview of Change
This PR enables clang-tidy
bugprone-use-after-movecheck.Context of Change
Type of Change
.gitignore, formatting, dropping support for older tooling)API Impact
No impact.
libxrplchange (any change that may affectlibxrplor dependents oflibxrpl)