Skip to content

Commit

Permalink
Make SCOPE_EXIT ODR safe
Browse files Browse the repository at this point in the history
Summary: `SCOPE_EXIT` macro is actively used in headers but it uses `__COUNTER__` that gives different value in different TU depending on number of previous `__COUNTER__` usages in translation unit. Therefore it violates ODR because function bodies for the same function become different. Clang detects this ODR violations in modularized builds when it merges AST from different modules or between global fragment and module. This diff create ODR safe version of `FB_ANONYMOUS_VARIABLE` that gives stable value but has limitation that it cannot be used more than once on the same line.

Reviewed By: Gownta

Differential Revision: D63825595

fbshipit-source-id: 7994094df5430a7e58bc51ef6576eae20b5cea0e
  • Loading branch information
Dmitry Polukhin authored and facebook-github-bot committed Oct 7, 2024
1 parent e4a205f commit 60c53af
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 6 deletions.
4 changes: 4 additions & 0 deletions folly/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@
#else
#define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__)
#endif
// FB_ANONYMOUS_VARIABLE_ODR_SAFE doesn't rely on __COUNTER__ and is safe to use
// in headers that should not violate the one-definition rule (ODR). It is
// especially useful for C++ modules that check for ODR violations.
#define FB_ANONYMOUS_VARIABLE_ODR_SAFE(str) FB_CONCATENATE(str, __LINE__)
#endif

/**
Expand Down
12 changes: 6 additions & 6 deletions folly/ScopeGuard.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
*
* @def SCOPE_EXIT
*/
#define SCOPE_EXIT \
auto FB_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) = \
#define SCOPE_EXIT \
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_EXIT_STATE) = \
::folly::detail::ScopeGuardOnExit() + [&]() noexcept

// SCOPE_FAIL
Expand Down Expand Up @@ -386,8 +386,8 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
*
* @def SCOPE_FAIL
*/
#define SCOPE_FAIL \
auto FB_ANONYMOUS_VARIABLE(SCOPE_FAIL_STATE) = \
#define SCOPE_FAIL \
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_FAIL_STATE) = \
::folly::detail::ScopeGuardOnFail() + [&]() noexcept

// SCOPE_SUCCESS
Expand Down Expand Up @@ -415,6 +415,6 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
*
* @def SCOPE_SUCCESS
*/
#define SCOPE_SUCCESS \
auto FB_ANONYMOUS_VARIABLE(SCOPE_SUCCESS_STATE) = \
#define SCOPE_SUCCESS \
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_SUCCESS_STATE) = \
::folly::detail::ScopeGuardOnSuccess() + [&]()

0 comments on commit 60c53af

Please sign in to comment.