Commit 27cfbc10 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Remove some [[noreturn]] functions

Summary: [Folly] Remove some `[[noreturn]]` functions - many of them can be replaced with `throw_exception`.

Reviewed By: Orvid

Differential Revision: D9624966

fbshipit-source-id: e5e472c660677112edf99e30e36d78c1b1718b52
parent 685a2941
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <type_traits> #include <type_traits>
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/lang/Exception.h>
#include <folly/portability/Time.h> #include <folly/portability/Time.h>
/*** /***
...@@ -159,11 +160,6 @@ constexpr std::chrono::time_point<Clock, To> round( ...@@ -159,11 +160,6 @@ constexpr std::chrono::time_point<Clock, To> round(
namespace folly { namespace folly {
namespace chrono { namespace chrono {
namespace detail {
[[noreturn]] FOLLY_NOINLINE inline void throw_coarse_steady_clock_now_exn() {
throw std::runtime_error("Error using CLOCK_MONOTONIC_COARSE.");
}
} // namespace detail
struct coarse_steady_clock { struct coarse_steady_clock {
using rep = std::chrono::milliseconds::rep; using rep = std::chrono::milliseconds::rep;
...@@ -180,7 +176,8 @@ struct coarse_steady_clock { ...@@ -180,7 +176,8 @@ struct coarse_steady_clock {
timespec ts; timespec ts;
auto ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); auto ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
if (ret != 0) { if (ret != 0) {
detail::throw_coarse_steady_clock_now_exn(); throw_exception<std::runtime_error>(
"Error using CLOCK_MONOTONIC_COARSE.");
} }
return time_point(std::chrono::duration_cast<duration>( return time_point(std::chrono::duration_cast<duration>(
std::chrono::seconds(ts.tv_sec) + std::chrono::seconds(ts.tv_sec) +
...@@ -188,5 +185,6 @@ struct coarse_steady_clock { ...@@ -188,5 +185,6 @@ struct coarse_steady_clock {
#endif #endif
} }
}; };
} // namespace chrono } // namespace chrono
} // namespace folly } // namespace folly
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <folly/FormatTraits.h> #include <folly/FormatTraits.h>
#include <folly/MapUtil.h> #include <folly/MapUtil.h>
#include <folly/Traits.h> #include <folly/Traits.h>
#include <folly/lang/Exception.h>
#include <folly/portability/Windows.h> #include <folly/portability/Windows.h>
// Ignore -Wformat-nonliteral warnings within this file // Ignore -Wformat-nonliteral warnings within this file
...@@ -184,7 +185,8 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()( ...@@ -184,7 +185,8 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(
p = q; p = q;
if (p == end || *p != '}') { if (p == end || *p != '}') {
throwBadFormatArg("folly::format: single '}' in format string"); throw_exception<BadFormatArg>(
"folly::format: single '}' in format string");
} }
++p; ++p;
} }
...@@ -206,7 +208,8 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()( ...@@ -206,7 +208,8 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(
p = q + 1; p = q + 1;
if (p == end) { if (p == end) {
throwBadFormatArg("folly::format: '}' at end of format string"); throw_exception<BadFormatArg>(
"folly::format: '}' at end of format string");
} }
// "{{" -> "{" // "{{" -> "{"
...@@ -219,7 +222,7 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()( ...@@ -219,7 +222,7 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(
// Format string // Format string
q = static_cast<const char*>(memchr(p, '}', size_t(end - p))); q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
if (q == nullptr) { if (q == nullptr) {
throwBadFormatArg("folly::format: missing ending '}'"); throw_exception<BadFormatArg>("folly::format: missing ending '}'");
} }
FormatArg arg(StringPiece(p, q)); FormatArg arg(StringPiece(p, q));
p = q + 1; p = q + 1;
...@@ -268,7 +271,7 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()( ...@@ -268,7 +271,7 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(
} }
if (hasDefaultArgIndex && hasExplicitArgIndex) { if (hasDefaultArgIndex && hasExplicitArgIndex) {
throwBadFormatArg( throw_exception<BadFormatArg>(
"folly::format: may not have both default and explicit arg indexes"); "folly::format: may not have both default and explicit arg indexes");
} }
...@@ -294,10 +297,10 @@ namespace format_value { ...@@ -294,10 +297,10 @@ namespace format_value {
template <class FormatCallback> template <class FormatCallback>
void formatString(StringPiece val, FormatArg& arg, FormatCallback& cb) { void formatString(StringPiece val, FormatArg& arg, FormatCallback& cb) {
if (arg.width != FormatArg::kDefaultWidth && arg.width < 0) { if (arg.width != FormatArg::kDefaultWidth && arg.width < 0) {
throwBadFormatArg("folly::format: invalid width"); throw_exception<BadFormatArg>("folly::format: invalid width");
} }
if (arg.precision != FormatArg::kDefaultPrecision && arg.precision < 0) { if (arg.precision != FormatArg::kDefaultPrecision && arg.precision < 0) {
throwBadFormatArg("folly::format: invalid precision"); throw_exception<BadFormatArg>("folly::format: invalid precision");
} }
if (arg.precision != FormatArg::kDefaultPrecision && if (arg.precision != FormatArg::kDefaultPrecision &&
...@@ -957,7 +960,7 @@ struct KeyableTraitsAssoc : public FormatTraitsBase { ...@@ -957,7 +960,7 @@ struct KeyableTraitsAssoc : public FormatTraitsBase {
if (auto ptr = get_ptr(map, KeyFromStringPiece<key_type>::convert(key))) { if (auto ptr = get_ptr(map, KeyFromStringPiece<key_type>::convert(key))) {
return *ptr; return *ptr;
} }
detail::throwFormatKeyNotFoundException(key); throw_exception<FormatKeyNotFoundException>(key);
} }
static const value_type& static const value_type&
at(const T& map, StringPiece key, const value_type& dflt) { at(const T& map, StringPiece key, const value_type& dflt) {
......
...@@ -422,10 +422,4 @@ FormatKeyNotFoundException::FormatKeyNotFoundException(StringPiece key) ...@@ -422,10 +422,4 @@ FormatKeyNotFoundException::FormatKeyNotFoundException(StringPiece key)
constexpr StringPiece const FormatKeyNotFoundException::kMessagePrefix; constexpr StringPiece const FormatKeyNotFoundException::kMessagePrefix;
namespace detail {
[[noreturn]] void throwFormatKeyNotFoundException(StringPiece key) {
throw FormatKeyNotFoundException(key);
}
} // namespace detail
} // namespace folly } // namespace folly
...@@ -331,10 +331,6 @@ class FOLLY_EXPORT FormatKeyNotFoundException : public std::out_of_range { ...@@ -331,10 +331,6 @@ class FOLLY_EXPORT FormatKeyNotFoundException : public std::out_of_range {
static constexpr StringPiece const kMessagePrefix = "format key not found: "; static constexpr StringPiece const kMessagePrefix = "format key not found: ";
}; };
namespace detail {
[[noreturn]] void throwFormatKeyNotFoundException(StringPiece key);
} // namespace detail
/** /**
* Wrap a sequence or associative container so that out-of-range lookups * Wrap a sequence or associative container so that out-of-range lookups
* return a default value rather than throwing an exception. * return a default value rather than throwing an exception.
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <folly/Likely.h> #include <folly/Likely.h>
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/lang/Exception.h>
namespace folly { namespace folly {
...@@ -30,9 +31,6 @@ class FOLLY_EXPORT BadFormatArg : public std::invalid_argument { ...@@ -30,9 +31,6 @@ class FOLLY_EXPORT BadFormatArg : public std::invalid_argument {
using invalid_argument::invalid_argument; using invalid_argument::invalid_argument;
}; };
[[noreturn]] void throwBadFormatArg(char const* msg);
[[noreturn]] void throwBadFormatArg(std::string const& msg);
/** /**
* Parsed format argument. * Parsed format argument.
*/ */
...@@ -215,7 +213,7 @@ inline std::string FormatArg::errorStr(Args&&... args) const { ...@@ -215,7 +213,7 @@ inline std::string FormatArg::errorStr(Args&&... args) const {
template <typename... Args> template <typename... Args>
[[noreturn]] inline void FormatArg::error(Args&&... args) const { [[noreturn]] inline void FormatArg::error(Args&&... args) const {
throwBadFormatArg(errorStr(std::forward<Args>(args)...)); throw_exception<BadFormatArg>(errorStr(std::forward<Args>(args)...));
} }
template <bool emptyOk> template <bool emptyOk>
......
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
namespace folly { namespace folly {
namespace detail { namespace detail {
[[noreturn]] void throwBadPolyAccess() { throw BadPolyAccess(); }
[[noreturn]] void throwBadPolyCast() { throw BadPolyCast(); } // empty
} // namespace detail } // namespace detail
} // namespace folly } // namespace folly
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define FOLLY_INLINE_CONSTEXPR inline constexpr #define FOLLY_INLINE_CONSTEXPR inline constexpr
#endif #endif
#include <folly/PolyException.h>
#include <folly/detail/PolyDetail.h> #include <folly/detail/PolyDetail.h>
namespace folly { namespace folly {
...@@ -173,27 +174,6 @@ struct PolyMembers {}; ...@@ -173,27 +174,6 @@ struct PolyMembers {};
#endif #endif
/**
* Exception type that is thrown on invalid access of an empty `Poly` object.
*/
struct FOLLY_EXPORT BadPolyAccess : std::exception {
BadPolyAccess() = default;
char const* what() const noexcept override {
return "BadPolyAccess";
}
};
/**
* Exception type that is thrown when attempting to extract from a `Poly` a
* value of the wrong type.
*/
struct FOLLY_EXPORT BadPolyCast : std::bad_cast {
BadPolyCast() = default;
char const* what() const noexcept override {
return "BadPolyCast";
}
};
/** /**
* Used in the definition of a `Poly` interface to say that the current * Used in the definition of a `Poly` interface to say that the current
* interface is an extension of a set of zero or more interfaces. * interface is an extension of a set of zero or more interfaces.
......
...@@ -14,14 +14,33 @@ ...@@ -14,14 +14,33 @@
* limitations under the License. * limitations under the License.
*/ */
#include <folly/FormatArg.h> #pragma once
#include <exception>
#include <folly/CPortability.h>
namespace folly { namespace folly {
[[noreturn]] void throwBadFormatArg(char const* msg) { /**
throw BadFormatArg(msg); * Exception type that is thrown on invalid access of an empty `Poly` object.
} */
[[noreturn]] void throwBadFormatArg(std::string const& msg) { struct FOLLY_EXPORT BadPolyAccess : std::exception {
throw BadFormatArg(msg); BadPolyAccess() = default;
} char const* what() const noexcept override {
return "BadPolyAccess";
}
};
/**
* Exception type that is thrown when attempting to extract from a `Poly` a
* value of the wrong type.
*/
struct FOLLY_EXPORT BadPolyCast : std::bad_cast {
BadPolyCast() = default;
char const* what() const noexcept override {
return "BadPolyCast";
}
};
} // namespace folly } // namespace folly
...@@ -184,10 +184,6 @@ void singletonPrintDestructionStackTrace(const TypeDescriptor& type) { ...@@ -184,10 +184,6 @@ void singletonPrintDestructionStackTrace(const TypeDescriptor& type) {
type.name()); type.name());
} }
[[noreturn]] void SingletonVaultState::throwUnexpectedState(const char* msg) {
throw std::logic_error(msg);
}
} // namespace detail } // namespace detail
namespace { namespace {
......
...@@ -129,6 +129,7 @@ ...@@ -129,6 +129,7 @@
#include <folly/detail/StaticSingletonManager.h> #include <folly/detail/StaticSingletonManager.h>
#include <folly/experimental/ReadMostlySharedPtr.h> #include <folly/experimental/ReadMostlySharedPtr.h>
#include <folly/hash/Hash.h> #include <folly/hash/Hash.h>
#include <folly/lang/Exception.h>
#include <folly/synchronization/Baton.h> #include <folly/synchronization/Baton.h>
#include <folly/synchronization/RWSpinLock.h> #include <folly/synchronization/RWSpinLock.h>
...@@ -271,11 +272,9 @@ struct SingletonVaultState { ...@@ -271,11 +272,9 @@ struct SingletonVaultState {
Type expected, Type expected,
const char* msg = "Unexpected singleton state change") const { const char* msg = "Unexpected singleton state change") const {
if (expected != state) { if (expected != state) {
throwUnexpectedState(msg); throw_exception<std::logic_error>(msg);
} }
} }
[[noreturn]] static void throwUnexpectedState(const char* msg);
}; };
// This interface is used by SingletonVault to interact with SingletonHolders. // This interface is used by SingletonVault to interact with SingletonHolders.
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include <folly/Utility.h> #include <folly/Utility.h>
#include <folly/detail/TypeList.h> #include <folly/detail/TypeList.h>
#include <folly/functional/Invoke.h> #include <folly/functional/Invoke.h>
#include <folly/lang/Exception.h>
#include <folly/PolyException.h>
namespace folly { namespace folly {
/// \cond /// \cond
...@@ -243,9 +246,6 @@ using MembersOf = typename I::template Members<Uncvref<T>>; ...@@ -243,9 +246,6 @@ using MembersOf = typename I::template Members<Uncvref<T>>;
template <class I, class T> template <class I, class T>
using InterfaceOf = typename I::template Interface<T>; using InterfaceOf = typename I::template Interface<T>;
[[noreturn]] void throwBadPolyAccess();
[[noreturn]] void throwBadPolyCast();
#if !defined(__cpp_template_auto) #if !defined(__cpp_template_auto)
template <class T, T V> template <class T, T V>
using Member = std::integral_constant<T, V>; using Member = std::integral_constant<T, V>;
...@@ -440,7 +440,7 @@ struct ThrowThunk { ...@@ -440,7 +440,7 @@ struct ThrowThunk {
constexpr /* implicit */ operator FnPtr<R, Args...>() const noexcept { constexpr /* implicit */ operator FnPtr<R, Args...>() const noexcept {
struct _ { struct _ {
static R call(Args...) { static R call(Args...) {
throwBadPolyAccess(); throw_exception<BadPolyAccess>();
} }
}; };
return &_::call; return &_::call;
...@@ -598,7 +598,7 @@ void* execOnHeap(Op op, Data* from, void* to) { ...@@ -598,7 +598,7 @@ void* execOnHeap(Op op, Data* from, void* to) {
if (*static_cast<std::type_info const*>(to) == typeid(T)) { if (*static_cast<std::type_info const*>(to) == typeid(T)) {
return from->pobj_; return from->pobj_;
} }
throwBadPolyCast(); throw_exception<BadPolyCast>();
case Op::eRefr: case Op::eRefr:
return vtableForRef<I, Uncvref<T>>( return vtableForRef<I, Uncvref<T>>(
static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to))); static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to)));
...@@ -629,7 +629,7 @@ void* execOnHeap(Op op, Data* from, void* to) { ...@@ -629,7 +629,7 @@ void* execOnHeap(Op op, Data* from, void* to) {
if (*static_cast<std::type_info const*>(to) == typeid(T)) { if (*static_cast<std::type_info const*>(to) == typeid(T)) {
return from->pobj_; return from->pobj_;
} }
throwBadPolyCast(); throw_exception<BadPolyCast>();
case Op::eRefr: case Op::eRefr:
return vtableForRef<I, Uncvref<T>>( return vtableForRef<I, Uncvref<T>>(
static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to))); static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to)));
...@@ -660,7 +660,7 @@ void* execInSitu(Op op, Data* from, void* to) { ...@@ -660,7 +660,7 @@ void* execInSitu(Op op, Data* from, void* to) {
if (*static_cast<std::type_info const*>(to) == typeid(T)) { if (*static_cast<std::type_info const*>(to) == typeid(T)) {
return &from->buff_; return &from->buff_;
} }
throwBadPolyCast(); throw_exception<BadPolyCast>();
case Op::eRefr: case Op::eRefr:
return vtableForRef<I, Uncvref<T>>( return vtableForRef<I, Uncvref<T>>(
static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to))); static_cast<RefType>(reinterpret_cast<std::uintptr_t>(to)));
...@@ -670,7 +670,7 @@ void* execInSitu(Op op, Data* from, void* to) { ...@@ -670,7 +670,7 @@ void* execInSitu(Op op, Data* from, void* to) {
inline void* noopExec(Op op, Data*, void*) { inline void* noopExec(Op op, Data*, void*) {
if (op == Op::eAddr) if (op == Op::eAddr)
throwBadPolyAccess(); throw_exception<BadPolyAccess>();
return const_cast<void*>(static_cast<void const*>(&typeid(void))); return const_cast<void*>(static_cast<void const*>(&typeid(void)));
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <folly/Format.h> #include <folly/Format.h>
#include <folly/Likely.h> #include <folly/Likely.h>
#include <folly/detail/Iterators.h> #include <folly/detail/Iterators.h>
#include <folly/lang/Exception.h>
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
...@@ -93,14 +94,6 @@ struct FOLLY_EXPORT TypeError : std::runtime_error { ...@@ -93,14 +94,6 @@ struct FOLLY_EXPORT TypeError : std::runtime_error {
~TypeError() override; ~TypeError() override;
}; };
[[noreturn]] void throwTypeError_(
std::string const& expected,
dynamic::Type actual);
[[noreturn]] void throwTypeError_(
std::string const& expected,
dynamic::Type actual1,
dynamic::Type actual2);
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
namespace detail { namespace detail {
...@@ -122,7 +115,7 @@ struct Destroy { ...@@ -122,7 +115,7 @@ struct Destroy {
template <template <class> class Op> template <template <class> class Op>
dynamic numericOp(dynamic const& a, dynamic const& b) { dynamic numericOp(dynamic const& a, dynamic const& b) {
if (!a.isNumber() || !b.isNumber()) { if (!a.isNumber() || !b.isNumber()) {
throwTypeError_("numeric", a.type(), b.type()); throw_exception<TypeError>("numeric", a.type(), b.type());
} }
if (a.type() != b.type()) { if (a.type() != b.type()) {
auto& integ = a.isInt() ? a : b; auto& integ = a.isInt() ? a : b;
...@@ -556,13 +549,13 @@ inline dynamic& dynamic::operator/=(dynamic const& o) { ...@@ -556,13 +549,13 @@ inline dynamic& dynamic::operator/=(dynamic const& o) {
return *this; return *this;
} }
#define FB_DYNAMIC_INTEGER_OP(op) \ #define FB_DYNAMIC_INTEGER_OP(op) \
inline dynamic& dynamic::operator op(dynamic const& o) { \ inline dynamic& dynamic::operator op(dynamic const& o) { \
if (!isInt() || !o.isInt()) { \ if (!isInt() || !o.isInt()) { \
throwTypeError_("int64", type(), o.type()); \ throw_exception<TypeError>("int64", type(), o.type()); \
} \ } \
*getAddress<int64_t>() op o.asInt(); \ *getAddress<int64_t>() op o.asInt(); \
return *this; \ return *this; \
} }
FB_DYNAMIC_INTEGER_OP(%=) FB_DYNAMIC_INTEGER_OP(%=)
...@@ -650,7 +643,7 @@ template <class K, class V> inline void dynamic::insert(K&& key, V&& val) { ...@@ -650,7 +643,7 @@ template <class K, class V> inline void dynamic::insert(K&& key, V&& val) {
inline void dynamic::update(const dynamic& mergeObj) { inline void dynamic::update(const dynamic& mergeObj) {
if (!isObject() || !mergeObj.isObject()) { if (!isObject() || !mergeObj.isObject()) {
throwTypeError_("object", type(), mergeObj.type()); throw_exception<TypeError>("object", type(), mergeObj.type());
} }
for (const auto& pair : mergeObj.items()) { for (const auto& pair : mergeObj.items()) {
...@@ -660,7 +653,7 @@ inline void dynamic::update(const dynamic& mergeObj) { ...@@ -660,7 +653,7 @@ inline void dynamic::update(const dynamic& mergeObj) {
inline void dynamic::update_missing(const dynamic& mergeObj1) { inline void dynamic::update_missing(const dynamic& mergeObj1) {
if (!isObject() || !mergeObj1.isObject()) { if (!isObject() || !mergeObj1.isObject()) {
throwTypeError_("object", type(), mergeObj1.type()); throw_exception<TypeError>("object", type(), mergeObj1.type());
} }
// Only add if not already there // Only add if not already there
...@@ -802,7 +795,7 @@ T dynamic::asImpl() const { ...@@ -802,7 +795,7 @@ T dynamic::asImpl() const {
case STRING: case STRING:
return to<T>(*get_nothrow<std::string>()); return to<T>(*get_nothrow<std::string>());
default: default:
throwTypeError_("int/double/bool/string", type()); throw_exception<TypeError>("int/double/bool/string", type());
} }
} }
...@@ -872,7 +865,7 @@ T& dynamic::get() { ...@@ -872,7 +865,7 @@ T& dynamic::get() {
if (auto* p = get_nothrow<T>()) { if (auto* p = get_nothrow<T>()) {
return *p; return *p;
} }
throwTypeError_(TypeInfo<T>::name, type()); throw_exception<TypeError>(TypeInfo<T>::name, type());
} }
template <class T> template <class T>
......
...@@ -72,19 +72,6 @@ TypeError& TypeError::operator=(TypeError&&) noexcept( ...@@ -72,19 +72,6 @@ TypeError& TypeError::operator=(TypeError&&) noexcept(
std::is_nothrow_move_assignable<std::runtime_error>::value) = default; std::is_nothrow_move_assignable<std::runtime_error>::value) = default;
TypeError::~TypeError() = default; TypeError::~TypeError() = default;
[[noreturn]] void throwTypeError_(
std::string const& expected,
dynamic::Type actual) {
throw TypeError(expected, actual);
}
[[noreturn]] void throwTypeError_(
std::string const& expected,
dynamic::Type actual1,
dynamic::Type actual2) {
throw TypeError(expected, actual1, actual2);
}
// This is a higher-order preprocessor macro to aid going from runtime // This is a higher-order preprocessor macro to aid going from runtime
// types to the compile time type system. // types to the compile time type system.
#define FB_DYNAMIC_APPLY(type, apply) \ #define FB_DYNAMIC_APPLY(type, apply) \
...@@ -119,7 +106,7 @@ TypeError::~TypeError() = default; ...@@ -119,7 +106,7 @@ TypeError::~TypeError() = default;
bool dynamic::operator<(dynamic const& o) const { bool dynamic::operator<(dynamic const& o) const {
if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) { if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) {
throwTypeError_("object", type_); throw_exception<TypeError>("object", type_);
} }
if (type_ != o.type_) { if (type_ != o.type_) {
return type_ < o.type_; return type_ < o.type_;
...@@ -182,7 +169,7 @@ dynamic& dynamic::operator=(dynamic&& o) noexcept { ...@@ -182,7 +169,7 @@ dynamic& dynamic::operator=(dynamic&& o) noexcept {
dynamic& dynamic::operator[](dynamic const& k) & { dynamic& dynamic::operator[](dynamic const& k) & {
if (!isObject() && !isArray()) { if (!isObject() && !isArray()) {
throwTypeError_("object/array", type()); throw_exception<TypeError>("object/array", type());
} }
if (isArray()) { if (isArray()) {
return at(k); return at(k);
...@@ -229,7 +216,7 @@ dynamic dynamic::getDefault(const dynamic& k, dynamic&& v) && { ...@@ -229,7 +216,7 @@ dynamic dynamic::getDefault(const dynamic& k, dynamic&& v) && {
const dynamic* dynamic::get_ptr(dynamic const& idx) const& { const dynamic* dynamic::get_ptr(dynamic const& idx) const& {
if (auto* parray = get_nothrow<Array>()) { if (auto* parray = get_nothrow<Array>()) {
if (!idx.isInt()) { if (!idx.isInt()) {
throwTypeError_("int64", idx.type()); throw_exception<TypeError>("int64", idx.type());
} }
if (idx < 0 || idx >= parray->size()) { if (idx < 0 || idx >= parray->size()) {
return nullptr; return nullptr;
...@@ -242,19 +229,14 @@ const dynamic* dynamic::get_ptr(dynamic const& idx) const& { ...@@ -242,19 +229,14 @@ const dynamic* dynamic::get_ptr(dynamic const& idx) const& {
} }
return &it->second; return &it->second;
} else { } else {
throwTypeError_("object/array", type()); throw_exception<TypeError>("object/array", type());
} }
} }
[[noreturn]] static void throwOutOfRangeAtMissingKey(dynamic const& idx) {
auto msg = sformat("couldn't find key {} in dynamic object", idx.asString());
throw_exception<std::out_of_range>(msg);
}
dynamic const& dynamic::at(dynamic const& idx) const& { dynamic const& dynamic::at(dynamic const& idx) const& {
if (auto* parray = get_nothrow<Array>()) { if (auto* parray = get_nothrow<Array>()) {
if (!idx.isInt()) { if (!idx.isInt()) {
throwTypeError_("int64", idx.type()); throw_exception<TypeError>("int64", idx.type());
} }
if (idx < 0 || idx >= parray->size()) { if (idx < 0 || idx >= parray->size()) {
throw_exception<std::out_of_range>("out of range in dynamic array"); throw_exception<std::out_of_range>("out of range in dynamic array");
...@@ -263,11 +245,14 @@ dynamic const& dynamic::at(dynamic const& idx) const& { ...@@ -263,11 +245,14 @@ dynamic const& dynamic::at(dynamic const& idx) const& {
} else if (auto* pobject = get_nothrow<ObjectImpl>()) { } else if (auto* pobject = get_nothrow<ObjectImpl>()) {
auto it = pobject->find(idx); auto it = pobject->find(idx);
if (it == pobject->end()) { if (it == pobject->end()) {
throwOutOfRangeAtMissingKey(idx); invoke_noreturn_cold([&] {
throw_exception<std::out_of_range>(
sformat("couldn't find key {} in dynamic object", idx.asString()));
});
} }
return it->second; return it->second;
} else { } else {
throwTypeError_("object/array", type()); throw_exception<TypeError>("object/array", type());
} }
} }
...@@ -281,7 +266,7 @@ std::size_t dynamic::size() const { ...@@ -281,7 +266,7 @@ std::size_t dynamic::size() const {
if (auto* str = get_nothrow<std::string>()) { if (auto* str = get_nothrow<std::string>()) {
return str->size(); return str->size();
} }
throwTypeError_("array/object", type()); throw_exception<TypeError>("array/object", type());
} }
dynamic::iterator dynamic::erase(const_iterator first, const_iterator last) { dynamic::iterator dynamic::erase(const_iterator first, const_iterator last) {
...@@ -384,7 +369,7 @@ const dynamic* dynamic::get_ptr(json_pointer const& jsonPtr) const& { ...@@ -384,7 +369,7 @@ const dynamic* dynamic::get_ptr(json_pointer const& jsonPtr) const& {
dyn = dyn->get_ptr(""); dyn = dyn->get_ptr("");
continue; continue;
} }
throwTypeError_("object", dyn->type()); throw_exception<TypeError>("object", dyn->type());
} }
if (auto* parray = dyn->get_nothrow<dynamic::Array>()) { if (auto* parray = dyn->get_nothrow<dynamic::Array>()) {
if (token.size() > 1 && token.at(0) == '0') { if (token.size() > 1 && token.at(0) == '0') {
...@@ -405,7 +390,7 @@ const dynamic* dynamic::get_ptr(json_pointer const& jsonPtr) const& { ...@@ -405,7 +390,7 @@ const dynamic* dynamic::get_ptr(json_pointer const& jsonPtr) const& {
dyn = it != pobject->end() ? &it->second : nullptr; dyn = it != pobject->end() ? &it->second : nullptr;
continue; continue;
} }
throwTypeError_("object/array", dyn->type()); throw_exception<TypeError>("object/array", dyn->type());
} }
return dyn; return dyn;
} }
......
...@@ -28,8 +28,5 @@ namespace ssl { ...@@ -28,8 +28,5 @@ namespace ssl {
"expected out of size {} but was of size {}", size, out.size())); "expected out of size {} but was of size {}", size, out.size()));
} }
[[noreturn]] void OpenSSLHash::check_libssl_result_throw() {
throw std::runtime_error("openssl crypto function failed");
}
} // namespace ssl } // namespace ssl
} // namespace folly } // namespace folly
...@@ -177,9 +177,9 @@ class OpenSSLHash { ...@@ -177,9 +177,9 @@ class OpenSSLHash {
if (LIKELY(result == expected)) { if (LIKELY(result == expected)) {
return; return;
} }
check_libssl_result_throw(); throw_exception<std::runtime_error>("openssl crypto function failed");
} }
[[noreturn]] static void check_libssl_result_throw();
}; };
} // namespace ssl } // namespace ssl
} // namespace folly } // namespace folly
...@@ -231,7 +231,7 @@ BENCHMARK_DRAW_LINE(); ...@@ -231,7 +231,7 @@ BENCHMARK_DRAW_LINE();
BENCHMARK(throw_exception, iters) { BENCHMARK(throw_exception, iters) {
for (size_t n = 0; n < iters; ++n) { for (size_t n = 0; n < iters; ++n) {
try { try {
throwException(); folly::throw_exception<Exception>("this is a test");
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
} }
} }
......
...@@ -16,33 +16,17 @@ ...@@ -16,33 +16,17 @@
#include <folly/test/function_benchmark/test_functions.h> #include <folly/test/function_benchmark/test_functions.h>
#include <folly/lang/Exception.h>
/* /*
* These functions are defined in a separate file so that * These functions are defined in a separate file so that
* gcc won't be able to inline them. * gcc won't be able to inline them.
*/ */
class Exception : public std::exception {
public:
explicit Exception(const std::string& value) : value_(value) {}
~Exception() noexcept override {}
const char* what() const noexcept override {
return value_.c_str();
}
private:
std::string value_;
};
void doNothing() { void doNothing() {
} }
[[noreturn]]
void throwException() {
throw Exception("this is a test");
}
std::exception_ptr returnExceptionPtr() { std::exception_ptr returnExceptionPtr() {
Exception ex("this is a test"); Exception ex("this is a test");
return std::make_exception_ptr(ex); return std::make_exception_ptr(ex);
......
...@@ -22,9 +22,21 @@ ...@@ -22,9 +22,21 @@
#include <folly/Function.h> #include <folly/Function.h>
class Exception : public std::exception {
public:
explicit Exception(const std::string& value) : value_(value) {}
~Exception() noexcept override {}
const char* what() const noexcept override {
return value_.c_str();
}
private:
std::string value_;
};
void doNothing(); void doNothing();
[[noreturn]] void throwException();
std::exception_ptr returnExceptionPtr(); std::exception_ptr returnExceptionPtr();
void exceptionPtrReturnParam(std::exception_ptr* excReturn); void exceptionPtrReturnParam(std::exception_ptr* excReturn);
std::string returnString(); std::string returnString();
......
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