Skip to content

Commit 7b7ba2d

Browse files
Add ABSL_ATTRIBUTE_LIFETIME_BOUND attribute on Map, RepeatedField and RepeatedPtrField.
This allows the compiler to statically detect use-after-free bugs. PiperOrigin-RevId: 532245526
1 parent 78ad093 commit 7b7ba2d

File tree

3 files changed

+168
-114
lines changed

3 files changed

+168
-114
lines changed

src/google/protobuf/map.h

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#endif
5252

5353
#include "google/protobuf/stubs/common.h"
54+
#include "absl/base/attributes.h"
5455
#include "absl/container/btree_map.h"
5556
#include "absl/hash/hash.h"
5657
#include "absl/meta/type_traits.h"
@@ -1135,7 +1136,7 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
11351136
}
11361137
}
11371138

1138-
Map& operator=(Map&& other) noexcept {
1139+
Map& operator=(Map&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
11391140
if (this != &other) {
11401141
if (arena() != other.arena()) {
11411142
*this = other;
@@ -1300,38 +1301,44 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13001301
friend class Map;
13011302
};
13021303

1303-
iterator begin() { return iterator(this); }
1304-
iterator end() { return iterator(); }
1305-
const_iterator begin() const { return const_iterator(this); }
1306-
const_iterator end() const { return const_iterator(); }
1307-
const_iterator cbegin() const { return begin(); }
1308-
const_iterator cend() const { return end(); }
1304+
iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { return iterator(this); }
1305+
iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { return iterator(); }
1306+
const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1307+
return const_iterator(this);
1308+
}
1309+
const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1310+
return const_iterator();
1311+
}
1312+
const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1313+
return begin();
1314+
}
1315+
const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); }
13091316

13101317
using Base::empty;
13111318
using Base::size;
13121319

13131320
// Element access
13141321
template <typename K = key_type>
1315-
T& operator[](const key_arg<K>& key) {
1322+
T& operator[](const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
13161323
return try_emplace(key).first->second;
13171324
}
13181325
template <
13191326
typename K = key_type,
13201327
// Disable for integral types to reduce code bloat.
13211328
typename = typename std::enable_if<!std::is_integral<K>::value>::type>
1322-
T& operator[](key_arg<K>&& key) {
1329+
T& operator[](key_arg<K>&& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
13231330
return try_emplace(std::forward<K>(key)).first->second;
13241331
}
13251332

13261333
template <typename K = key_type>
1327-
const T& at(const key_arg<K>& key) const {
1334+
const T& at(const key_arg<K>& key) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
13281335
const_iterator it = find(key);
13291336
ABSL_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
13301337
return it->second;
13311338
}
13321339

13331340
template <typename K = key_type>
1334-
T& at(const key_arg<K>& key) {
1341+
T& at(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
13351342
iterator it = find(key);
13361343
ABSL_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
13371344
return it->second;
@@ -1344,11 +1351,12 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13441351
}
13451352

13461353
template <typename K = key_type>
1347-
const_iterator find(const key_arg<K>& key) const {
1354+
const_iterator find(const key_arg<K>& key) const
1355+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
13481356
return const_cast<Map*>(this)->find(key);
13491357
}
13501358
template <typename K = key_type>
1351-
iterator find(const key_arg<K>& key) {
1359+
iterator find(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
13521360
auto res = this->FindHelper(key);
13531361
return iterator(static_cast<Node*>(res.node), this, res.bucket);
13541362
}
@@ -1360,7 +1368,7 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13601368

13611369
template <typename K = key_type>
13621370
std::pair<const_iterator, const_iterator> equal_range(
1363-
const key_arg<K>& key) const {
1371+
const key_arg<K>& key) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
13641372
const_iterator it = find(key);
13651373
if (it == end()) {
13661374
return std::pair<const_iterator, const_iterator>(it, it);
@@ -1371,7 +1379,8 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13711379
}
13721380

13731381
template <typename K = key_type>
1374-
std::pair<iterator, iterator> equal_range(const key_arg<K>& key) {
1382+
std::pair<iterator, iterator> equal_range(const key_arg<K>& key)
1383+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
13751384
iterator it = find(key);
13761385
if (it == end()) {
13771386
return std::pair<iterator, iterator>(it, it);
@@ -1383,7 +1392,8 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13831392

13841393
// insert
13851394
template <typename K, typename... Args>
1386-
std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
1395+
std::pair<iterator, bool> try_emplace(K&& k, Args&&... args)
1396+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
13871397
// Inserts a new element into the container if there is no element with the
13881398
// key in the container.
13891399
// The new element is:
@@ -1395,16 +1405,18 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
13951405
std::forward<K>(k),
13961406
std::forward<Args>(args)...);
13971407
}
1398-
std::pair<iterator, bool> insert(init_type&& value) {
1408+
std::pair<iterator, bool> insert(init_type&& value)
1409+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
13991410
return try_emplace(std::move(value.first), std::move(value.second));
14001411
}
14011412
template <typename P, RequiresInsertable<P> = 0>
1402-
std::pair<iterator, bool> insert(P&& value) {
1413+
std::pair<iterator, bool> insert(P&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
14031414
return try_emplace(std::forward<P>(value).first,
14041415
std::forward<P>(value).second);
14051416
}
14061417
template <typename... Args>
1407-
std::pair<iterator, bool> emplace(Args&&... args) {
1418+
std::pair<iterator, bool> emplace(Args&&... args)
1419+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
14081420
return EmplaceInternal(Rank0{}, std::forward<Args>(args)...);
14091421
}
14101422
template <class InputIt>
@@ -1435,7 +1447,7 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
14351447
}
14361448
}
14371449

1438-
iterator erase(iterator pos) {
1450+
iterator erase(iterator pos) ABSL_ATTRIBUTE_LIFETIME_BOUND {
14391451
auto next = std::next(pos);
14401452
ABSL_DCHECK_EQ(pos.m_, static_cast<Base*>(this));
14411453
auto* node = static_cast<Node*>(pos.node_);
@@ -1475,7 +1487,7 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
14751487
}
14761488

14771489
// Assign
1478-
Map& operator=(const Map& other) {
1490+
Map& operator=(const Map& other) ABSL_ATTRIBUTE_LIFETIME_BOUND {
14791491
if (this != &other) {
14801492
clear();
14811493
insert(other.begin(), other.end());

0 commit comments

Comments
 (0)