Adding 'lifetimebound' annotations to ICU4C

25 views
Skip to first unread message

Fredrik Roubert

unread,
Jan 15, 2026, 6:27:23 AMJan 15
to icu-d...@unicode.org, Markus Scherer
Dear ICU Team & Users,

I would like to propose the following API for: ICU 79
Please provide feedback by: next Wednesday, 2026-01-21
Designated API reviewer: Markus
Ticket: ICU-23310

(The "ICU 79 API proposal status" document is still marked as TODO, so
instead I just added this proposal to the old "ICU 78 API proposal
status" from where it later can be easily cut'n'pasted.)

There's a pretty new C++ feature called lifetimebound, currently
supported by newer versions of the Clang and MSVC compilers (and
possibly others):

https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
https://learn.microsoft.com/en-us/cpp/code-quality/c26816?view=msvc-170

While it doesn't turn C++ into Rust quite yet, it makes it possible
for the compiler to emit warnings or errors for a bunch of easily made
memory bugs that are otherwise hard to detect.

I therefore propose adding a new ICU4C macro for the feature:


#ifndef __cplusplus
// Not for C.
#elif defined(U_LIFETIME_BOUND)
// Use the predefined value.
#elif UPRV_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
# define U_LIFETIME_BOUND [[clang::lifetimebound]]
#elif UPRV_HAS_CPP_ATTRIBUTE(msvc::lifetimebound)
# define U_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif UPRV_HAS_ATTRIBUTE(lifetimebound)
# define U_LIFETIME_BOUND __attribute__((lifetimebound))
#endif


With that in place, I'd then proceed to annotate ICU4C functions like this:


U_COMMON_API const char* getName() const U_LIFETIME_BOUND;

static const Locale& getLocale(
const Locale& valid U_LIFETIME_BOUND,
const Locale& actual U_LIFETIME_BOUND,
ULocDataLocaleType type, UErrorCode& status);


That will make it possible for the compiler to detect the memory bugs
in code like this:


const char* p = Locale("hi").getName();

const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
ULOC_VALID_LOCALE, status);


Such code would then result in compiler errors like these:


error: temporary whose address is used as value of local variable 'p'
will be destroyed at the end of the full-expression
[-Werror,-Wdangling]
const char* p = Locale("hi").getName();
^~~~~~~~~~~~

error: temporary bound to local reference 'l' will be destroyed at the
end of the full-expression [-Werror,-Wdangling]
const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
^~~~~~~~~~~~
error: temporary bound to local reference 'l' will be destroyed at the
end of the full-expression [-Werror,-Wdangling]
const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
^~~~~~~~~~~~

So when all the above is in place, I furthermore propose adding
-Wdangling to the default compiler options.

--
Fredrik Roubert
rou...@google.com

Markus Scherer

unread,
Jan 16, 2026, 11:44:12 AMJan 16
to Fredrik Roubert, icu-d...@unicode.org
all lgtm, tnx!
markus
Reply all
Reply to author
Forward
0 new messages