mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 13:17:35 +00:00
AK+Everywhere: Disallow returning a reference from a fallible expression
This will silently make a copy. Rather than masking this behavior, let's explicitly disallow it.
This commit is contained in:
parent
3de75f6436
commit
afc0e461e1
11 changed files with 86 additions and 54 deletions
8
AK/Try.h
8
AK/Try.h
|
@ -15,12 +15,18 @@
|
||||||
// on statement expressions [1]. This is known to be implemented
|
// on statement expressions [1]. This is known to be implemented
|
||||||
// by at least clang and gcc.
|
// by at least clang and gcc.
|
||||||
// [1] https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
|
// [1] https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
|
||||||
|
//
|
||||||
|
// If the static_assert below is triggered, it means you tried to return a reference
|
||||||
|
// from a fallible expression. This will not do what you want; the statement expression
|
||||||
|
// will create a copy regardless, so it is explicitly disallowed.
|
||||||
|
|
||||||
#define TRY(expression) \
|
#define TRY(expression) \
|
||||||
({ \
|
({ \
|
||||||
/* Ignore -Wshadow to allow nesting the macro. */ \
|
/* Ignore -Wshadow to allow nesting the macro. */ \
|
||||||
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
|
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
|
||||||
auto _temporary_result = (expression)); \
|
auto _temporary_result = (expression)); \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
if (_temporary_result.is_error()) [[unlikely]] \
|
if (_temporary_result.is_error()) [[unlikely]] \
|
||||||
return _temporary_result.release_error(); \
|
return _temporary_result.release_error(); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
|
@ -31,6 +37,8 @@
|
||||||
/* Ignore -Wshadow to allow nesting the macro. */ \
|
/* Ignore -Wshadow to allow nesting the macro. */ \
|
||||||
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
|
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
|
||||||
auto _temporary_result = (expression)); \
|
auto _temporary_result = (expression)); \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
VERIFY(!_temporary_result.is_error()); \
|
VERIFY(!_temporary_result.is_error()); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
|
@ -189,6 +189,8 @@ private:
|
||||||
auto result = (expression); \
|
auto result = (expression); \
|
||||||
if (result.is_error()) \
|
if (result.is_error()) \
|
||||||
return set_so_error(result.release_error()); \
|
return set_so_error(result.release_error()); \
|
||||||
|
static_assert(!IsLvalueReference<decltype(result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
result.release_value(); \
|
result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,8 @@ struct CLDR {
|
||||||
auto _temporary_result = (expression); \
|
auto _temporary_result = (expression); \
|
||||||
if (_temporary_result.is_error()) \
|
if (_temporary_result.is_error()) \
|
||||||
return; \
|
return; \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -71,5 +71,7 @@ struct LoaderError {
|
||||||
auto _temporary_result = (expression); \
|
auto _temporary_result = (expression); \
|
||||||
if (_temporary_result.is_error()) \
|
if (_temporary_result.is_error()) \
|
||||||
return LoaderError(_temporary_result.release_error()); \
|
return LoaderError(_temporary_result.release_error()); \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace JS {
|
||||||
VERIFY(_temporary_result.error().code() == ENOMEM); \
|
VERIFY(_temporary_result.error().code() == ENOMEM); \
|
||||||
return vm.throw_completion<JS::InternalError>(JS::ErrorType::OutOfMemory); \
|
return vm.throw_completion<JS::InternalError>(JS::ErrorType::OutOfMemory); \
|
||||||
} \
|
} \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ private:
|
||||||
return (capability)->promise(); \
|
return (capability)->promise(); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_try_or_reject_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
|
\
|
||||||
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
||||||
_temporary_try_or_reject_result.release_value(); \
|
_temporary_try_or_reject_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
@ -76,6 +79,9 @@ private:
|
||||||
return Value { (capability)->promise() }; \
|
return Value { (capability)->promise() }; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_try_or_reject_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
|
\
|
||||||
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
||||||
_temporary_try_or_reject_result.release_value(); \
|
_temporary_try_or_reject_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
|
@ -85,6 +85,8 @@ private:
|
||||||
return DecoderError::from_source_location( \
|
return DecoderError::from_source_location( \
|
||||||
((category)), _error_string, SourceLocation::current()); \
|
((category)), _error_string, SourceLocation::current()); \
|
||||||
} \
|
} \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_result.release_value(); \
|
_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,8 @@ bool PlaybackManager::decode_and_queue_one_sample()
|
||||||
m_present_timer->start(0); \
|
m_present_timer->start(0); \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace Web::Fetch::Fetching {
|
||||||
auto _temporary_result = (expression); \
|
auto _temporary_result = (expression); \
|
||||||
if (_temporary_result.is_error()) \
|
if (_temporary_result.is_error()) \
|
||||||
return; \
|
return; \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace Web::WebDriver {
|
||||||
auto _temporary_result = (expression); \
|
auto _temporary_result = (expression); \
|
||||||
if (_temporary_result.is_error()) [[unlikely]] \
|
if (_temporary_result.is_error()) [[unlikely]] \
|
||||||
return ExecuteScriptResultType::JavaScriptError; \
|
return ExecuteScriptResultType::JavaScriptError; \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
outln("Encountered a parsing error: {}", _temporary_result.error().string_literal()); \
|
outln("Encountered a parsing error: {}", _temporary_result.error().string_literal()); \
|
||||||
return Error::from_string_literal("Failed to parse :("); \
|
return Error::from_string_literal("Failed to parse :("); \
|
||||||
} \
|
} \
|
||||||
|
static_assert(!IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
|
"Do not return a reference from a fallible expression"); \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue