diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-01-13 15:48:09 -0500 |
---|---|---|
committer | Tim Flynn <trflynn89@pm.me> | 2023-01-13 18:50:47 -0500 |
commit | afc0e461e123489808930e5433f0d8b3f95d9256 (patch) | |
tree | 0ac45b4bbc1c55890555cddf394b2d056502e9ea /AK/Try.h | |
parent | 3de75f6436a1e729691a40c35e8e8a5be5aa2f41 (diff) | |
download | serenity-afc0e461e123489808930e5433f0d8b3f95d9256.zip |
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.
Diffstat (limited to 'AK/Try.h')
-rw-r--r-- | AK/Try.h | 38 |
1 files changed, 23 insertions, 15 deletions
@@ -15,22 +15,30 @@ // on statement expressions [1]. This is known to be implemented // by at least clang and gcc. // [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) \ - ({ \ - /* Ignore -Wshadow to allow nesting the macro. */ \ - AK_IGNORE_DIAGNOSTIC("-Wshadow", \ - auto _temporary_result = (expression)); \ - if (_temporary_result.is_error()) [[unlikely]] \ - return _temporary_result.release_error(); \ - _temporary_result.release_value(); \ +#define TRY(expression) \ + ({ \ + /* Ignore -Wshadow to allow nesting the macro. */ \ + AK_IGNORE_DIAGNOSTIC("-Wshadow", \ + 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]] \ + return _temporary_result.release_error(); \ + _temporary_result.release_value(); \ }) -#define MUST(expression) \ - ({ \ - /* Ignore -Wshadow to allow nesting the macro. */ \ - AK_IGNORE_DIAGNOSTIC("-Wshadow", \ - auto _temporary_result = (expression)); \ - VERIFY(!_temporary_result.is_error()); \ - _temporary_result.release_value(); \ +#define MUST(expression) \ + ({ \ + /* Ignore -Wshadow to allow nesting the macro. */ \ + AK_IGNORE_DIAGNOSTIC("-Wshadow", \ + 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()); \ + _temporary_result.release_value(); \ }) |