diff --git a/CMakeLists.txt b/CMakeLists.txt index 52c9250bc..c2a1435ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang") set(OT_CFLAGS $<$:${OT_CFLAGS} -Wall -Wformat-nonliteral -Wextra -Wshadow> $<$:${OT_CFLAGS} -Wall -Wformat-nonliteral -Wextra -Wshadow -Wno-c++14-compat -fno-exceptions> - $<$:-Wc99-extensions> + $<$:-Wc99-extensions -Wno-unknown-warning-option -Wdangling -Wdangling-gsl -Wdangling-assignment -Wdangling-field -Wreturn-stack-address> ) endif() diff --git a/include/openthread/instance.h b/include/openthread/instance.h index eae225a80..72b0926d2 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -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 diff --git a/include/openthread/platform/toolchain.h b/include/openthread/platform/toolchain.h index 0084f9f92..28cbbd659 100644 --- a/include/openthread/platform/toolchain.h +++ b/include/openthread/platform/toolchain.h @@ -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 + /** * @} */ diff --git a/src/core/common/heap_string.hpp b/src/core/common/heap_string.hpp index 0a019e50a..a5f60329b 100644 --- a/src/core/common/heap_string.hpp +++ b/src/core/common/heap_string.hpp @@ -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 +class OT_GSL_OWNER String : public Unequatable { 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(*this); } + String &&Move(void) OT_LIFETIME_BOUND { return static_cast(*this); } /** * Frees any buffer allocated by the `String`.