Summary:Use C++'s standardized `[[noreturn]]` attribute.
All supported compilers (and some unsupported compilers) also support the standardized syntax.
GCC >= 4.8, Clang >= 3.0, and MSVC >= 2015 have direct support for the C++'s standardized way of writing the attribute.
Clang - http://goo.gl/ftJGVM
GCC 4.8.2 - http://goo.gl/ORCVOD
ICC 13.0.1 - http://goo.gl/I5tn5I
MSVC 2015 - https://msdn.microsoft.com/en-us/library/hh567368.aspx
(Regardling Clang, earlier versions may support it. 3.0 was the earliest Clang version listed at godbolt.com, so that's as far back as I went.)
Therefore, we no longer need to use the compiler-specific syntaxes, or use preprocessor macros with per-compiler definitions:
__attribute__((__noreturn__))
__attribute__((noreturn))
__declspec(noreturn)
Reviewed By: Orvid
Differential Revision:
D3073621
fb-gh-sync-id:
32d4771d1bf1974693b8574fa2d39c9559872945
shipit-source-id:
32d4771d1bf1974693b8574fa2d39c9559872945
// The *Explicit functions take an explicit value for errno.
// Helper to throw std::system_error
-FOLLY_NORETURN void throwSystemErrorExplicit(int err, const char*);
-inline void throwSystemErrorExplicit(int err, const char* msg) {
+[[noreturn]] inline void throwSystemErrorExplicit(int err, const char* msg) {
throw std::system_error(err, std::system_category(), msg);
}
template <class... Args>
-FOLLY_NORETURN void throwSystemErrorExplicit(int, Args&&... args);
-template <class... Args>
-void throwSystemErrorExplicit(int err, Args&&... args) {
+[[noreturn]] void throwSystemErrorExplicit(int err, Args&&... args) {
throwSystemErrorExplicit(
err, to<fbstring>(std::forward<Args>(args)...).c_str());
}
// Helper to throw std::system_error from errno and components of a string
template <class... Args>
-FOLLY_NORETURN void throwSystemError(Args&&... args);
-template <class... Args>
-void throwSystemError(Args&&... args) {
+[[noreturn]] void throwSystemError(Args&&... args) {
throwSystemErrorExplicit(errno, std::forward<Args>(args)...);
}
template <typename... Args>
std::string errorStr(Args&&... args) const;
template <typename... Args>
- FOLLY_NORETURN void error(Args&&... args) const;
+ [[noreturn]] void error(Args&&... args) const;
/**
* Full argument string, as passed in to the constructor.
}
}
- FOLLY_NORETURN FOLLY_NOINLINE static void fail() {
+ [[noreturn]] FOLLY_NOINLINE static void fail() {
LOG(FATAL) << "Indestructible is not initialized";
}
# define FOLLY_DEPRECATED(msg)
#endif
-// noreturn
-#if defined(_MSC_VER)
-# define FOLLY_NORETURN __declspec(noreturn)
-#elif defined(__clang__) || defined(__GNUC__)
-# define FOLLY_NORETURN __attribute__((__noreturn__))
-#else
-# define FOLLY_NORETURN
-#endif
-
// noinline
#ifdef _MSC_VER
# define FOLLY_NOINLINE __declspec(noinline)
namespace folly { namespace detail {
-FOLLY_NORETURN void assertionFailure(const char* expr, const char* msg,
- const char* file, unsigned int line,
- const char* function);
-
+[[noreturn]] void assertionFailure(
+ const char* expr,
+ const char* msg,
+ const char* file,
+ unsigned int line,
+ const char* function);
}} // namespace folly
#endif /* FOLLY_SAFEASSERT_H_ */
int errnoValue;
};
-FOLLY_NORETURN void childError(int errFd, int errCode, int errnoValue);
-void childError(int errFd, int errCode, int errnoValue) {
+[[noreturn]] void childError(int errFd, int errCode, int errnoValue) {
ChildErrorInfo info = {errCode, errnoValue};
// Write the error information over the pipe to our parent process.
// We can't really do anything else if this write call fails.
FOLLY_NAMESPACE_STD_BEGIN
-FOLLY_NORETURN void __throw_length_error(const char* msg);
-FOLLY_NORETURN void __throw_logic_error(const char* msg);
-FOLLY_NORETURN void __throw_out_of_range(const char* msg);
+[[noreturn]] void __throw_length_error(const char* msg);
+[[noreturn]] void __throw_logic_error(const char* msg);
+[[noreturn]] void __throw_out_of_range(const char* msg);
#ifdef _MSC_VER
-FOLLY_NORETURN void __throw_bad_alloc();
+[[noreturn]] void __throw_bad_alloc();
#endif
FOLLY_NAMESPACE_STD_END
static dynamic parseBser(Cursor& curs);
template <typename... ARGS>
-static FOLLY_NORETURN void throwDecodeError(Cursor& curs, ARGS&&... args) {
+[[noreturn]] static void throwDecodeError(Cursor& curs, ARGS&&... args) {
throw BserDecodeError(folly::to<std::string>(std::forward<ARGS>(args)...,
" with ",
curs.length(),
namespace __cxxabiv1 {
extern "C" {
-FOLLY_NORETURN void __cxa_throw(void* thrownException,
- std::type_info* type,
- void (*destructor)(void*));
+void __cxa_throw(
+ void* thrownException,
+ std::type_info* type,
+ void (*destructor)(void*)) __attribute__((__noreturn__));
void* __cxa_begin_catch(void* excObj) throw();
-FOLLY_NORETURN void __cxa_rethrow(void);
+void __cxa_rethrow(void) __attribute__((__noreturn__));
void __cxa_rethrow(void);
void __cxa_end_catch(void);
}
namespace {
-FOLLY_NORETURN void usage(const char* name);
-
-void usage(const char* name) {
+[[noreturn]] void usage(const char* name) {
std::cerr << folly::format(
"Usage: {0}\n"
" list all huge page sizes and their mount points\n"
size_t lineNumber_ = 0;
};
-FOLLY_NORETURN void throwOutputError() {
+[[noreturn]] void throwOutputError() {
throw OutputError(folly::errnoStr(errno).toStdString());
}
-FOLLY_NORETURN void throwInputError() {
+[[noreturn]] void throwInputError() {
throw InputError(folly::errnoStr(errno).toStdString());
}