Adding assertions will aid users that have bugs in their code to receive better error messages.
Details
- Reviewers
ldionne - Group Reviewers
Restricted Project - Commits
- rG5e807c38bf9b: [libc++] add basic runtime assertions to <latch>
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I am learning how to use this differential tool and it appears the previous patch undid the changes I actually intended to commit instead of removing just the "one" offending line in regards to unrelated formatting changes.
I should have fixed the issue and now the actual diff file should be complete.
Sorry
Thanks for the patch! If you upload the patch with arc, it should also include some context in the diff, which is useful. Let us know if you run into issues with that.
libcxx/include/latch | ||
---|---|---|
75 | Not attached: Can you please add some tests for these assertions? To see how we do this for other assertions: libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp. | |
80–81 | I think it is also UB if __expected > max(), right? If so, let's add an assertion. | |
91–92 | I read:
So we can actually check more than just __update >= 0. | |
112–113 | Same here:
|
libcxx/include/latch | ||
---|---|---|
80–81 | You are right but in this implementation because max is equivalent to std::numeric_limits<ptrdiff_t>::max() it should not be possible |
libcxx/include/latch | ||
---|---|---|
80–81 | Then the compiler can probably elide the check, but we should still have the check! |
I addressed the review.
Please note the following:
Because in the llvm's implementation max() returns the max value of ptrdiff_t" (numeric_limits<ptrdiff_t>::max();) It should not be possible to check for that in an assertion.
Note that I used memory_order_relaxed in the assertions as that seems to be the memory order that has the potential to cause less collateral damage. Let me know if it's fine please.
Thanks
libcxx/include/latch | ||
---|---|---|
80–81 | I see, I just saw your comment. I will add the check right away. |
Added an assertions to check that when the latch object is constructed "n" is not greater than max
libcxx/include/latch | ||
---|---|---|
80–81 | I added the check. That should be the last point to address from your previous review. I hope all is good now. Thanks 🐱 |
I added the check for "n is greater than max()". That should be the last point to address from your previous review. I hope all is good now. Thanks 🐱
libcxx/include/latch | ||
---|---|---|
95–99 | Could we instead move the _LIBCPP_ASSERT after the fetch_sub, i.e. do: _LIBCPP_ASSERT_UNCATEGORIZED( __update >= 0, "latch::count_down called with a negative value"); auto const __old = __a_.fetch_sub(__update, memory_order_release); _LIBCPP_ASSERT_UNCATEGORIZED( __update > __old, "__update is greater than the value of the internal counter"); This would not require an additional atomic load, yet we would catch that we just did something really really bad (i.e. that __a_ is now negative and who knows what will happen next). | |
libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp | ||
2 | Let's also add a assert.ctor.pass.cpp test to test the assertion you added in the constructor! |
Added ctor unit test.
Correct assertion placement.
Remove one assertion as I realized that immediately after we are calling a function with the same kind of assertion. So perhaps it's not worth it to call .load() to check for the internal counter when we have a similar test right after that is checked without calling any extra operations
I am a bit concerned about these new tests apparently failing because I, unfortunately, I don't know why they are failing despite me checking them over and over again for mistakes. I need to learn all of this.
I realized by looking at already existing tests that my ctor.pass is incorrect. I will try to fix it in a few hours
Make sure the tests messages match the assertions messages from libcxx (should fix the tests)
libcxx/include/latch | ||
---|---|---|
117–118 | To avoid being inconsistent, I think I would remove this assertion and add a comment saying // preconditions on __update are checked in count_down(). | |
libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp | ||
34 | You should do this instead: TEST_LIBCPP_ASSERT_FAILURE([]{ std::latch foo(-1); }(), "assertion message"); // and add a comment that we can't check the precondition for max() because there's no value that would violate the precondition (in our implementation) |
Hopefully, that should do it. I am happy I made progress with these tests earlier today. Was a bit hard to figure out but now they should turn green.
LGTM, thanks! If you need someone to commit this on your behalf, please let us know Author Name <email@domain> to use for attribution.
Not attached: Can you please add some tests for these assertions? To see how we do this for other assertions: libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp.