This is an archive of the discontinued LLVM Phabricator instance.

[RFC] Add _LIBCPP_NO_DISCARD and apply it to `Container::empty()`, `unique_ptr<T>::release()`, and `Lockable::try_lock()`
Needs RevisionPublic

Authored by EricWF on Nov 13 2016, 1:30 PM.

Details

Summary

This patch adds the _LIBCPP_NO_DISCARD macro and applies it to various functions including:

  • unique_ptr<T>::release()
  • The empty(), size(), capacity() and max_size() methods of STL Containers and std::string.
  • try_lock(), try_lock_for() and try_lock_until() of lockable types.

I just want to check that we agree on the general direction of this patch. Specifically that libc++ should be free to apply no_discard where we feel appropriate.

Additional suggestions welcome!

This patch fixes PR30898 (https://llvm.org/bugs/show_bug.cgi?id=30898)

Diff Detail

Event Timeline

EricWF updated this revision to Diff 77758.Nov 13 2016, 1:30 PM
EricWF retitled this revision from to [RFC] Add _LIBCPP_NO_DISCARD and apply it to unique_ptr<T>::release().
EricWF updated this object.
EricWF added reviewers: mclow.lists, chandlerc.
EricWF added a subscriber: cfe-commits.
EricWF updated this object.Nov 13 2016, 1:33 PM
chandlerc edited edge metadata.Nov 13 2016, 2:18 PM

I think we want dedicated macros to disable each added [[nodiscard]]. The reason is that as you add each one, users will have to roll out cleanups for the new warnings. This may be hard to do quickly and cause problems updating libc++ for users with -Werror in their build. I'd prefer it if users can initially add a macro to disable the attribute until their cleanup is complete.

There should also be a page documenting all of the APIs that use this and the macros to control them.

mclow.lists edited edge metadata.Nov 13 2016, 4:07 PM

I think we want dedicated macros to disable each added [[nodiscard]].

My concern here is that I expect that there will be a lot of these.
Off the top of my head, I can name:

  • Every smart pointer's get() and release()
  • Every container's empty()
  • A bunch of algorithms (find(), find_if(), search(), and lower/upper_bound() leap to mind, but that's not an exhaustive list)

Note: I'm not unsympathetic to the situation that Chandler describes; I just don't want to manage a potentially unbounded (but probably more than 20) set of macros.

EricWF updated this revision to Diff 77760.Nov 13 2016, 4:35 PM
EricWF retitled this revision from [RFC] Add _LIBCPP_NO_DISCARD and apply it to unique_ptr<T>::release() to [RFC] Add _LIBCPP_NO_DISCARD and apply it to `Container::empty()`, `unique_ptr<T>::release()`, and `Lockable::try_lock()` .
EricWF updated this object.
EricWF edited edge metadata.
  • Allow groups of no-discard checks to be enabled/disabled using group specific macros. (As requested by @chandlerc)
  • Add documentation for _LIBCPP_NO_DISCARD and friends.
  • Apply no-discard checks in more places to show new feature macro example.

@chandlerc Would this approach be sufficient?

EricWF updated this revision to Diff 77761.Nov 13 2016, 4:37 PM
  • Add missing newlines in added tests.
EricWF updated this revision to Diff 77762.Nov 13 2016, 4:56 PM
  • Apply no-discard to string_view::empty() and friends.
  • Fix discarded use of unique_ptr<T>::release() within libc++.
EricWF updated this revision to Diff 77763.Nov 13 2016, 5:05 PM
  • Fix even more instances of unique_ptr<T>::release() with a discarded value. Hopefully this is the last of them.
EricWF updated this revision to Diff 77764.Nov 13 2016, 5:16 PM
  • Fix tests containing discarded values.
  • Fix two more instances of discarded unique_ptr<T>::release() in the headers.
EricWF updated this revision to Diff 77769.Nov 13 2016, 9:46 PM
  • Add [[no_discard]] to various smart pointer observers including get() and operator*().
EricWF updated this revision to Diff 77772.Nov 14 2016, 12:18 AM

Add final touches. This patch is ready to go.

@chandlerc mentioned he would still like to see more per-function granularity for enabling/disabling the libc++ [[nodiscard]] macro in order to ease adoption in large code bases. However I'm concerned about the cost of maintaining 100+ user-visible configuration macros. This current patch attempts to find a happy medium by grouping similar functions into a single macro; which can be sub-divided further if needed.

As a general rule functions where [[nodiscard]] may yield false positives (ie unique_ptr::release()) should always have their own group, since fixing the false-positives is a stylistic change. Functions where a discarded value is always a bug, either for correctness reasons (ie try_lock()) or because the call has no side-effects (ie string::empty), may be grouped together as appropriate; Warnings generated by these groups should either be rare or high priority bugs. Dividing groups in this manner attempts to maximize adaptability while being reasonably maintainable.

@mclow.lists Any last words?

mclow.lists requested changes to this revision.Feb 7 2018, 3:43 PM

Since we've implemented P0600, I believe that this patch is out of date.
The correct macro is _LIBCPP_NODISCARD_AFTER_CXX17, and I think that several of these cases are now handled.

This revision now requires changes to proceed.Feb 7 2018, 3:43 PM