[common] add Clang lifetime safety annotations to Message (#13422)

This commit applies Clang Lifetime Safety Analysis annotations to the
message buffer and chunk classes in `src/core/common/message.hpp`:

- Annotates `Message` with `OT_GSL_OWNER` to designate it as a root
  resource owner representing an OpenThread message buffer chain.
- Annotates view and iterator classes (`ConstIterator`, `Iterator`,
  `Chunk`, and `MutableChunk`) with `OT_GSL_POINTER` as non-owning
  borrowers over message buffers.
- Annotates buffer, chunk, and link reference accessors (`GetMetadata()`,
  `GetFirstData()`, `GetData()`, `MutableChunk::GetBytes()`, `Next()`,
  and `Prev()`) with `OT_LIFETIME_BOUND` so the compiler verifies that
  derived pointers and references do not outlive the message buffer chain.
This commit is contained in:
Jonathan Hui
2026-07-27 14:22:47 -07:00
committed by GitHub
parent b547da0fd8
commit 5974ece8c7
+18 -17
View File
@@ -262,14 +262,14 @@ protected:
static constexpr uint16_t kBufferDataSize = kSize - sizeof(otMessageBuffer);
static constexpr uint16_t kHeadBufferDataSize = kBufferDataSize - sizeof(Metadata);
Metadata &GetMetadata(void) { return mBuffer.mHead.mMetadata; }
const Metadata &GetMetadata(void) const { return mBuffer.mHead.mMetadata; }
Metadata &GetMetadata(void) OT_LIFETIME_BOUND { return mBuffer.mHead.mMetadata; }
const Metadata &GetMetadata(void) const OT_LIFETIME_BOUND { return mBuffer.mHead.mMetadata; }
uint8_t *GetFirstData(void) { return mBuffer.mHead.mData; }
const uint8_t *GetFirstData(void) const { return mBuffer.mHead.mData; }
uint8_t *GetFirstData(void) OT_LIFETIME_BOUND { return mBuffer.mHead.mData; }
const uint8_t *GetFirstData(void) const OT_LIFETIME_BOUND { return mBuffer.mHead.mData; }
uint8_t *GetData(void) { return mBuffer.mData; }
const uint8_t *GetData(void) const { return mBuffer.mData; }
uint8_t *GetData(void) OT_LIFETIME_BOUND { return mBuffer.mData; }
const uint8_t *GetData(void) const OT_LIFETIME_BOUND { return mBuffer.mData; }
private:
union
@@ -289,7 +289,7 @@ static_assert(sizeof(Buffer) >= Buffer::kSize,
/**
* Represents a message.
*/
class Message : public otMessage, public Buffer, public GetProvider<Message>
class OT_GSL_OWNER Message : public otMessage, public Buffer, public GetProvider<Message>
{
friend class Checksum;
friend class CrcCalculator<uint16_t>;
@@ -1596,7 +1596,7 @@ public:
#endif // #if OPENTHREAD_CONFIG_MULTI_RADIO
protected:
class ConstIterator : public ItemPtrIterator<const Message, ConstIterator>
class OT_GSL_POINTER ConstIterator : public ItemPtrIterator<const Message, ConstIterator>
{
friend class ItemPtrIterator<const Message, ConstIterator>;
@@ -1612,7 +1612,7 @@ protected:
void Advance(void) { mItem = mItem->GetNext(); }
};
class Iterator : public ItemPtrIterator<Message, Iterator>
class OT_GSL_POINTER Iterator : public ItemPtrIterator<Message, Iterator>
{
friend class ItemPtrIterator<Message, Iterator>;
@@ -1639,20 +1639,21 @@ protected:
void SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }
private:
class Chunk : public Data<kWithUint16Length>
class OT_GSL_POINTER Chunk : public Data<kWithUint16Length>
{
public:
const Buffer *GetBuffer(void) const { return mBuffer; }
// Note: `GetBytes() const OT_LIFETIME_BOUND` is inherited from `Data<kWithUint16Length>`.
const Buffer *GetBuffer(void) const OT_LIFETIME_BOUND { return mBuffer; }
void SetBuffer(const Buffer *aBuffer) { mBuffer = aBuffer; }
private:
const Buffer *mBuffer; // Buffer containing the chunk
};
class MutableChunk : public Chunk
class OT_GSL_POINTER MutableChunk : public Chunk
{
public:
uint8_t *GetBytes(void) { return AsNonConst(Chunk::GetBytes()); }
uint8_t *GetBytes(void) OT_LIFETIME_BOUND { return AsNonConst(Chunk::GetBytes()); }
};
void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk) const;
@@ -1675,10 +1676,10 @@ private:
void SetRssAverager(const RssAverager &aRssAverager) { GetMetadata().mRssAverager = aRssAverager; }
void SetLqiAverager(const LqiAverager &aLqiAverager) { GetMetadata().mLqiAverager = aLqiAverager; }
Message *&Next(void) { return GetMetadata().mNext; }
Message *const &Next(void) const { return GetMetadata().mNext; }
Message *&Prev(void) { return GetMetadata().mPrev; }
Message *const &Prev(void) const { return GetMetadata().mPrev; }
Message *&Next(void) OT_LIFETIME_BOUND { return GetMetadata().mNext; }
Message *const &Next(void) const OT_LIFETIME_BOUND { return GetMetadata().mNext; }
Message *&Prev(void) OT_LIFETIME_BOUND { return GetMetadata().mPrev; }
Message *const &Prev(void) const OT_LIFETIME_BOUND { return GetMetadata().mPrev; }
static Message *NextOf(Message *aMessage) { return (aMessage != nullptr) ? aMessage->Next() : nullptr; }
static const Message *NextOf(const Message *aMessage) { return (aMessage != nullptr) ? aMessage->Next() : nullptr; }