summaryrefslogtreecommitdiff
path: root/AK/Try.h
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-01-13 15:48:09 -0500
committerTim Flynn <trflynn89@pm.me>2023-01-13 18:50:47 -0500
commitafc0e461e123489808930e5433f0d8b3f95d9256 (patch)
tree0ac45b4bbc1c55890555cddf394b2d056502e9ea /AK/Try.h
parent3de75f6436a1e729691a40c35e8e8a5be5aa2f41 (diff)
downloadserenity-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.h38
1 files changed, 23 insertions, 15 deletions
diff --git a/AK/Try.h b/AK/Try.h
index 772f0d6608..81b0fca9f3 100644
--- a/AK/Try.h
+++ b/AK/Try.h
@@ -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(); \
})