Mark fallible container operations as `nodiscard`
It's evidently too easy to ignore the return values of these operations.
After all, ignoring allocation failures is the normal pattern in most
C++ code.
Thus this change marks these functions as `nodiscard`. This does require
a few CHECKs in test code, but it also catches one real instance of a
problem.
Change-Id: I24432506283145fc2f459336fe1035cbca27bd4f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/75187
Commit-Queue: Adam Langley <agl@google.com>
Auto-Submit: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/handoff.cc b/ssl/handoff.cc
index bd409f2..610ad6f 100644
--- a/ssl/handoff.cc
+++ b/ssl/handoff.cc
@@ -668,8 +668,10 @@
}
s3->session_reused = session_reused;
hs->channel_id_negotiated = channel_id_negotiated;
- s3->next_proto_negotiated.CopyFrom(next_proto);
- s3->alpn_selected.CopyFrom(alpn);
+ if (!s3->next_proto_negotiated.CopyFrom(next_proto) ||
+ !s3->alpn_selected.CopyFrom(alpn)) {
+ return false;
+ }
const size_t hostname_len = CBS_len(&hostname);
if (hostname_len == 0) {
diff --git a/ssl/internal.h b/ssl/internal.h
index 0f3da92..bf8bf36 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -161,7 +161,7 @@
// value-constructed copies of |T|. It returns true on success and false on
// error. If |T| is a primitive type like |uint8_t|, value-construction means
// it will be zero-initialized.
- bool Init(size_t new_size) {
+ [[nodiscard]] bool Init(size_t new_size) {
if (!InitUninitialized(new_size)) {
return false;
}
@@ -172,7 +172,7 @@
// InitForOverwrite behaves like |Init| but it default-constructs each element
// instead. This means that, if |T| is a primitive type, the array will be
// uninitialized and thus must be filled in by the caller.
- bool InitForOverwrite(size_t new_size) {
+ [[nodiscard]] bool InitForOverwrite(size_t new_size) {
if (!InitUninitialized(new_size)) {
return false;
}
@@ -182,7 +182,7 @@
// CopyFrom replaces the array with a newly-allocated copy of |in|. It returns
// true on success and false on error.
- bool CopyFrom(Span<const T> in) {
+ [[nodiscard]] bool CopyFrom(Span<const T> in) {
if (!InitUninitialized(in.size())) {
return false;
}
@@ -273,7 +273,7 @@
// Push adds |elem| at the end of the internal array, growing if necessary. It
// returns false when allocation fails.
- bool Push(T elem) {
+ [[nodiscard]] bool Push(T elem) {
if (!MaybeGrow()) {
return false;
}
@@ -284,7 +284,7 @@
// CopyFrom replaces the contents of the array with a copy of |in|. It returns
// true on success and false on allocation error.
- bool CopyFrom(Span<const T> in) {
+ [[nodiscard]] bool CopyFrom(Span<const T> in) {
Array<T> copy;
if (!copy.CopyFrom(in)) {
return false;
@@ -406,7 +406,7 @@
// TryResize resizes the vector to |new_size| and returns true, or returns
// false if |new_size| is too large. Any newly-added elements are
// value-initialized.
- bool TryResize(size_t new_size) {
+ [[nodiscard]] bool TryResize(size_t new_size) {
if (new_size <= size_) {
Shrink(new_size);
return true;
@@ -422,7 +422,7 @@
// TryResizeForOverwrite behaves like |TryResize|, but newly-added elements
// are default-initialized, so POD types may contain uninitialized values that
// the caller is responsible for filling in.
- bool TryResizeForOverwrite(size_t new_size) {
+ [[nodiscard]] bool TryResizeForOverwrite(size_t new_size) {
if (new_size <= size_) {
Shrink(new_size);
return true;
@@ -437,7 +437,7 @@
// TryCopyFrom sets the vector to a copy of |in| and returns true, or returns
// false if |in| is too large.
- bool TryCopyFrom(Span<const T> in) {
+ [[nodiscard]] bool TryCopyFrom(Span<const T> in) {
if (in.size() > capacity()) {
return false;
}
@@ -449,7 +449,7 @@
// TryPushBack appends |val| to the vector and returns a pointer to the
// newly-inserted value, or nullptr if the vector is at capacity.
- T *TryPushBack(T val) {
+ [[nodiscard]] T *TryPushBack(T val) {
if (size() >= capacity()) {
return nullptr;
}
diff --git a/ssl/ssl_internal_test.cc b/ssl/ssl_internal_test.cc
index 230018f..ae251dc 100644
--- a/ssl/ssl_internal_test.cc
+++ b/ssl/ssl_internal_test.cc
@@ -120,15 +120,15 @@
TEST(VectorTest, NotDefaultConstructible) {
struct NotDefaultConstructible {
- explicit NotDefaultConstructible(size_t n) { array.Init(n); }
+ explicit NotDefaultConstructible(size_t n) { BSSL_CHECK(array.Init(n)); }
Array<int> array;
};
Vector<NotDefaultConstructible> vec;
- vec.Push(NotDefaultConstructible(0));
- vec.Push(NotDefaultConstructible(1));
- vec.Push(NotDefaultConstructible(2));
- vec.Push(NotDefaultConstructible(3));
+ ASSERT_TRUE(vec.Push(NotDefaultConstructible(0)));
+ ASSERT_TRUE(vec.Push(NotDefaultConstructible(1)));
+ ASSERT_TRUE(vec.Push(NotDefaultConstructible(2)));
+ ASSERT_TRUE(vec.Push(NotDefaultConstructible(3)));
EXPECT_EQ(vec.size(), 4u);
EXPECT_EQ(0u, vec[0].array.size());
EXPECT_EQ(1u, vec[1].array.size());