Commit fdcce5ae authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Mark invoker operator() as maybe-unused

Summary:
[Folly] Mark invoker `operator()` as `[[maybe_unused]]` when defined in macros.

If the macro is used in a `.cpp` but the generated `operator()` is not invoked, the compiler might warn.

This can easily happen in the following situation:

```
FOLLY_CREATE_MEMBER_INVOKER(invoke_foo_fn, foo);
FOLLY_CREATE_MEMBER_INVOKER(invoke_bar_fn, bar);

using invoke_one_fn = std::conditional_t<
    /* cond */,
    invoke_foo_fn,
    invoke_bar_fn>;
constexpr invoke_one_fn invoke_on;

template <typename T>
void go(T& t) {
  invoke_one(t);
}
```

In such a situation, either `invoke_foo_fn::operator()` is seen at a call-site or `invoke_bar_fn::operator()` is seen at the call-site, but not both - one of them is unused, and if the right warnings are enabled, will be warned as unused.

Reviewed By: luciang, markisaa

Differential Revision: D22570047

fbshipit-source-id: a4caa7a95ab74ea075cf41c26525935f3d9186c0
parent eeb59fc3
...@@ -77,10 +77,10 @@ ...@@ -77,10 +77,10 @@
* #endif * #endif
* } * }
*/ */
#if FOLLY_HAS_CPP_ATTRIBUTE(maybe_unused) #if FOLLY_HAS_CPP_ATTRIBUTE(maybe_unused) && __cplusplus >= 201703L
#define FOLLY_MAYBE_UNUSED [[maybe_unused]] #define FOLLY_MAYBE_UNUSED [[maybe_unused]]
#elif FOLLY_HAS_ATTRIBUTE(__unused__) || __GNUC__ #elif FOLLY_HAS_CPP_ATTRIBUTE(gnu::unused) || __GNUC__
#define FOLLY_MAYBE_UNUSED __attribute__((__unused__)) #define FOLLY_MAYBE_UNUSED [[gnu::unused]]
#else #else
#define FOLLY_MAYBE_UNUSED #define FOLLY_MAYBE_UNUSED
#endif #endif
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <boost/preprocessor/logical/not.hpp> #include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/tuple/to_list.hpp> #include <boost/preprocessor/tuple/to_list.hpp>
#include <folly/CppAttributes.h>
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/Preprocessor.h> #include <folly/Preprocessor.h>
#include <folly/Traits.h> #include <folly/Traits.h>
...@@ -365,7 +366,8 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> { ...@@ -365,7 +366,8 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> {
FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, __VA_ARGS__) \ FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, __VA_ARGS__) \
struct __folly_detail_invoke_obj { \ struct __folly_detail_invoke_obj { \
template <typename... Args> \ template <typename... Args> \
FOLLY_ERASE_HACK_GCC constexpr auto operator()(Args&&... args) const \ FOLLY_MAYBE_UNUSED FOLLY_ERASE_HACK_GCC constexpr auto operator()( \
Args&&... args) const \
noexcept(noexcept(funcname(static_cast<Args&&>(args)...))) \ noexcept(noexcept(funcname(static_cast<Args&&>(args)...))) \
-> decltype(funcname(static_cast<Args&&>(args)...)) { \ -> decltype(funcname(static_cast<Args&&>(args)...)) { \
return funcname(static_cast<Args&&>(args)...); \ return funcname(static_cast<Args&&>(args)...); \
...@@ -418,11 +420,11 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> { ...@@ -418,11 +420,11 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> {
#define FOLLY_CREATE_MEMBER_INVOKER(classname, membername) \ #define FOLLY_CREATE_MEMBER_INVOKER(classname, membername) \
struct classname { \ struct classname { \
template <typename O, typename... Args> \ template <typename O, typename... Args> \
FOLLY_ERASE_HACK_GCC constexpr auto operator()(O&& o, Args&&... args) \ FOLLY_MAYBE_UNUSED FOLLY_ERASE_HACK_GCC constexpr auto \
const noexcept(noexcept( \ operator()(O&& o, Args&&... args) const noexcept(noexcept( \
static_cast<O&&>(o).membername(static_cast<Args&&>(args)...))) \ static_cast<O&&>(o).membername(static_cast<Args&&>(args)...))) \
-> decltype(static_cast<O&&>(o).membername( \ -> decltype( \
static_cast<Args&&>(args)...)) { \ static_cast<O&&>(o).membername(static_cast<Args&&>(args)...)) { \
return static_cast<O&&>(o).membername(static_cast<Args&&>(args)...); \ return static_cast<O&&>(o).membername(static_cast<Args&&>(args)...); \
} \ } \
} }
...@@ -472,8 +474,8 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> { ...@@ -472,8 +474,8 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> {
template <typename T> \ template <typename T> \
struct classname { \ struct classname { \
template <typename... Args> \ template <typename... Args> \
FOLLY_ERASE constexpr auto operator()(Args&&... args) const \ FOLLY_MAYBE_UNUSED FOLLY_ERASE constexpr auto operator()(Args&&... args) \
noexcept(noexcept(T::membername(static_cast<Args&&>(args)...))) \ const noexcept(noexcept(T::membername(static_cast<Args&&>(args)...))) \
-> decltype(T::membername(static_cast<Args&&>(args)...)) { \ -> decltype(T::membername(static_cast<Args&&>(args)...)) { \
return T::membername(static_cast<Args&&>(args)...); \ return T::membername(static_cast<Args&&>(args)...); \
} \ } \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment