Summary:
Provide translations for gcc noreturn attribute
__attribute__((noreturn)) is gcc specific, clang understands it on nix systems, but for msvc __declspec(noreturn) is the compiler specific version, which clang will imitate/use on windows. There was already a FOLLY_NORETURN in portability.h, however because of __declspec limitations it must prefix the declaration, not postfix. The gcc noreturn attribute does not have this limitation and will work prefixed OR postfixed, so to keep from turning code into spaghetti nonsense, the macro was moved to the front of declations where it is currently used. This will allow it to work with the proper definitions on clang, clang on windows, gcc, and msvc
Test Plan: fbmake runtests
Reviewed By: delong.j@fb.com
FB internal diff:
D1279466
// The *Explicit functions take an explicit value for errno.
// Helper to throw std::system_error
-void throwSystemErrorExplicit(int err, const char*) FOLLY_NORETURN;
+FOLLY_NORETURN void throwSystemErrorExplicit(int err, const char*);
inline void throwSystemErrorExplicit(int err, const char* msg) {
throw std::system_error(err, std::system_category(), msg);
}
template <class... Args>
-void throwSystemErrorExplicit(int, Args&&... args) FOLLY_NORETURN;
+FOLLY_NORETURN void throwSystemErrorExplicit(int, Args&&... args);
template <class... Args>
void throwSystemErrorExplicit(int err, Args&&... args) {
throwSystemErrorExplicit(
// Helper to throw std::system_error from errno and components of a string
template <class... Args>
-void throwSystemError(Args&&... args) FOLLY_NORETURN;
+FOLLY_NORETURN void throwSystemError(Args&&... args);
template <class... Args>
void throwSystemError(Args&&... args) {
throwSystemErrorExplicit(errno, std::forward<Args>(args)...);
typename std::decay<Args>::type>...> ValueTuple;
static constexpr size_t valueCount = std::tuple_size<ValueTuple>::value;
- void handleFormatStrError() const FOLLY_NORETURN;
+ FOLLY_NORETURN void handleFormatStrError() const;
template <class Output>
void appendOutput(Output& out) const;
template <typename... Args>
std::string errorStr(Args&&... args) const;
template <typename... Args>
- void error(Args&&... args) const FOLLY_NORETURN;
+ FOLLY_NORETURN void error(Args&&... args) const;
/**
* Full argument string, as passed in to the constructor.
# error Cannot define MaxAlign on this platform
#endif
+// compiler specific attribute translation
+// msvc should come first, so if clang is in msvc mode it gets the right defines
// noreturn
-#if defined(__clang__) || defined(__GNUC__)
+#if defined(_MSC_VER)
+# define FOLLY_NORETURN __declspec(noreturn)
+#elif defined(__clang__) || defined(__GNUC__)
# define FOLLY_NORETURN __attribute__((noreturn))
#else
# define FOLLY_NORETURN
namespace folly { namespace detail {
-void assertionFailure(const char* expr, const char* msg, const char* file,
- unsigned int line, const char* function)
- FOLLY_NORETURN;
+FOLLY_NORETURN void assertionFailure(const char* expr, const char* msg,
+ const char* file, unsigned int line,
+ const char* function);
}} // namespace folly
int errnoValue;
};
-void childError(int errFd, int errCode, int errnoValue) FOLLY_NORETURN;
+FOLLY_NORETURN void childError(int errFd, int errCode, int errnoValue);
void childError(int errFd, int errCode, int errnoValue) {
ChildErrorInfo info = {errCode, errnoValue};
// Write the error information over the pipe to our parent process.
FOLLY_NAMESPACE_STD_BEGIN
-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) FOLLY_NORETURN;
+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);
FOLLY_NAMESPACE_STD_END
namespace __cxxabiv1 {
extern "C" {
-void __cxa_throw(void* thrownException, std::type_info* type,
- void (*destructor)(void)) FOLLY_NORETURN;
+FOLLY_NORETURN void __cxa_throw(void* thrownException,
+ std::type_info* type, void (*destructor)(void));
void* __cxa_begin_catch(void* excObj);
-void __cxa_rethrow(void) FOLLY_NORETURN;
+FOLLY_NORETURN void __cxa_rethrow(void);
void __cxa_end_catch(void);
}
pthread_once_t initialized = PTHREAD_ONCE_INIT;
extern "C" {
-typedef void (*CxaThrowType)(void*, std::type_info*, void (*)(void))
- FOLLY_NORETURN;
+FOLLY_NORETURN typedef void (*CxaThrowType)(void*, std::type_info*,
+ void (*)(void));
typedef void* (*CxaBeginCatchType)(void*);
-typedef void (*CxaRethrowType)(void)
- FOLLY_NORETURN;
+FOLLY_NORETURN typedef void (*CxaRethrowType)(void);
typedef void (*CxaEndCatchType)(void);
CxaThrowType orig_cxa_throw;
CxaEndCatchType orig_cxa_end_catch;
} // extern "C"
-typedef void (*RethrowExceptionType)(std::exception_ptr)
- FOLLY_NORETURN;
+FOLLY_NORETURN typedef void (*RethrowExceptionType)(std::exception_ptr);
RethrowExceptionType orig_rethrow_exception;
void initialize() {
namespace {
-void usage(const char* name) FOLLY_NORETURN;
+FOLLY_NORETURN void usage(const char* name);
void usage(const char* name) {
std::cerr << folly::format(