Skip to content

Commit 4273d1f

Browse files
Dmitry Polukhinfacebook-github-bot
authored andcommitted
Make SCOPE_EXIT ODR safe
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
1 parent 2184a67 commit 4273d1f

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

third-party/folly/src/folly/Preprocessor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100
#else
101101
#define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__)
102102
#endif
103+
// FB_ANONYMOUS_VARIABLE_ODR_SAFE doesn't rely on __COUNTER__ and is safe to use
104+
// in headers that should not violate the one-definition rule (ODR). It is
105+
// especially useful for C++ modules that check for ODR violations.
106+
#define FB_ANONYMOUS_VARIABLE_ODR_SAFE(str) FB_CONCATENATE(str, __LINE__)
103107
#endif
104108

105109
/**

third-party/folly/src/folly/ScopeGuard.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
356356
*
357357
* @def SCOPE_EXIT
358358
*/
359-
#define SCOPE_EXIT \
360-
auto FB_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) = \
359+
#define SCOPE_EXIT \
360+
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_EXIT_STATE) = \
361361
::folly::detail::ScopeGuardOnExit() + [&]() noexcept
362362

363363
// SCOPE_FAIL
@@ -386,8 +386,8 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
386386
*
387387
* @def SCOPE_FAIL
388388
*/
389-
#define SCOPE_FAIL \
390-
auto FB_ANONYMOUS_VARIABLE(SCOPE_FAIL_STATE) = \
389+
#define SCOPE_FAIL \
390+
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_FAIL_STATE) = \
391391
::folly::detail::ScopeGuardOnFail() + [&]() noexcept
392392

393393
// SCOPE_SUCCESS
@@ -415,6 +415,6 @@ ScopeGuardImpl<typename std::decay<FunctionType>::type, true> operator+(
415415
*
416416
* @def SCOPE_SUCCESS
417417
*/
418-
#define SCOPE_SUCCESS \
419-
auto FB_ANONYMOUS_VARIABLE(SCOPE_SUCCESS_STATE) = \
418+
#define SCOPE_SUCCESS \
419+
auto FB_ANONYMOUS_VARIABLE_ODR_SAFE(SCOPE_SUCCESS_STATE) = \
420420
::folly::detail::ScopeGuardOnSuccess() + [&]()

0 commit comments

Comments
 (0)