mirror of
https://github.com/espressif/openthread.git
synced 2026-09-25 02:17:39 +00:00
[common] add Clang lifetime safety macros and annotate Heap::String (#13381)
This commit introduces initial support for Clang's Lifetime Safety
Analysis across the OpenThread codebase:
1. Defines abstraction macros in `toolchain.h`:
- `OT_LIFETIME_BOUND` (`[[clang::lifetimebound]]`)
- `OT_NOESCAPE` (`[[clang::noescape]]`)
- `OT_GSL_OWNER` (`[[gsl::Owner]]`)
- `OT_GSL_POINTER` (`[[gsl::Pointer]]`)
These macros expand to Clang attributes under C++ LLVM builds
and gracefully degrade to no-ops or GNU attributes elsewhere.
2. Enables Clang lifetime warning flags in `CMakeLists.txt`:
- `-Wdangling` and `-Wdangling-gsl`
- `-Wdangling-assignment` and `-Wdangling-field`
- `-Wreturn-stack-address`
3. Annotates `Heap::String` (`heap_string.hpp`):
- Marks class `String` with `OT_GSL_OWNER`.
- Marks `AsCString()` and `Move()` with `OT_LIFETIME_BOUND` to
ensure returned C string pointers do not outlive the owner.
This commit is contained in:
+1
-1
@@ -99,7 +99,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
|
||||
set(OT_CFLAGS
|
||||
$<$<COMPILE_LANGUAGE:C>:${OT_CFLAGS} -Wall -Wformat-nonliteral -Wextra -Wshadow>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:${OT_CFLAGS} -Wall -Wformat-nonliteral -Wextra -Wshadow -Wno-c++14-compat -fno-exceptions>
|
||||
$<$<CXX_COMPILER_ID:Clang>:-Wc99-extensions>
|
||||
$<$<CXX_COMPILER_ID:Clang>:-Wc99-extensions -Wno-unknown-warning-option -Wdangling -Wdangling-gsl -Wdangling-assignment -Wdangling-field -Wreturn-stack-address>
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (613)
|
||||
#define OPENTHREAD_API_VERSION (614)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -310,6 +310,57 @@ extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OT_LIFETIME_BOUND
|
||||
*
|
||||
* Compiler-specific indication that a function or method return value's lifetime is bound to a parameter or `this`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def OT_NOESCAPE
|
||||
*
|
||||
* Compiler-specific indication that a pointer or reference parameter does not escape the function scope.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def OT_GSL_OWNER
|
||||
*
|
||||
* Compiler-specific indication that a class or struct is a resource owner for lifetime safety analysis.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def OT_GSL_POINTER
|
||||
*
|
||||
* Compiler-specific indication that a class or struct is a non-owning view or pointer for lifetime safety analysis.
|
||||
*/
|
||||
#if defined(__cplusplus) && defined(__clang__) && defined(__has_cpp_attribute)
|
||||
#if __has_cpp_attribute(clang::lifetimebound)
|
||||
#define OT_LIFETIME_BOUND [[clang::lifetimebound]]
|
||||
#endif
|
||||
#if __has_cpp_attribute(clang::noescape)
|
||||
#define OT_NOESCAPE [[clang::noescape]]
|
||||
#endif
|
||||
#if __has_cpp_attribute(gsl::Owner)
|
||||
#define OT_GSL_OWNER [[gsl::Owner]]
|
||||
#endif
|
||||
#if __has_cpp_attribute(gsl::Pointer)
|
||||
#define OT_GSL_POINTER [[gsl::Pointer]]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OT_LIFETIME_BOUND
|
||||
#define OT_LIFETIME_BOUND
|
||||
#endif
|
||||
#ifndef OT_NOESCAPE
|
||||
#define OT_NOESCAPE
|
||||
#endif
|
||||
#ifndef OT_GSL_OWNER
|
||||
#define OT_GSL_OWNER
|
||||
#endif
|
||||
#ifndef OT_GSL_POINTER
|
||||
#define OT_GSL_POINTER
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Heap {
|
||||
* be reused and/or freed and reallocated when the string is set. The `Heap::String` destructor will always free the
|
||||
* allocated buffer.
|
||||
*/
|
||||
class String : public Unequatable<String>
|
||||
class OT_GSL_OWNER String : public Unequatable<String>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
*
|
||||
* @returns A pointer to C string buffer or `nullptr` if the `String` is null (never set or freed).
|
||||
*/
|
||||
const char *AsCString(void) const { return mStringBuffer; }
|
||||
const char *AsCString(void) const OT_LIFETIME_BOUND { return mStringBuffer; }
|
||||
|
||||
/**
|
||||
* Sets the string from a given C string.
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
*
|
||||
* @returns An rvalue reference to this `String`.
|
||||
*/
|
||||
String &&Move(void) { return static_cast<String &&>(*this); }
|
||||
String &&Move(void) OT_LIFETIME_BOUND { return static_cast<String &&>(*this); }
|
||||
|
||||
/**
|
||||
* Frees any buffer allocated by the `String`.
|
||||
|
||||
Reference in New Issue
Block a user