Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions libc/src/__support/CPP/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ template <class T = void> struct bit_and {};
template <class T = void> struct bit_or {};
template <class T = void> struct bit_xor {};

template <class T>
LIBC_INLINE constexpr const T &max(LIBC_LIFETIME_BOUND const T &a,
LIBC_LIFETIME_BOUND const T &b) {
template <class T> LIBC_INLINE constexpr const T &max(const T &a, const T &b) {
return (a < b) ? b : a;
}

template <class T>
LIBC_INLINE constexpr const T &min(LIBC_LIFETIME_BOUND const T &a,
LIBC_LIFETIME_BOUND const T &b) {
template <class T> LIBC_INLINE constexpr const T &min(const T &a, const T &b) {
return (a < b) ? a : b;
}

Expand Down
19 changes: 6 additions & 13 deletions libc/src/__support/CPP/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,15 @@ template <class T, size_t N> struct array {
LIBC_INLINE constexpr T *data() { return Data; }
LIBC_INLINE constexpr const T *data() const { return Data; }

LIBC_INLINE constexpr T &front() LIBC_LIFETIME_BOUND { return Data[0]; }
LIBC_INLINE constexpr const T &front() const LIBC_LIFETIME_BOUND {
return Data[0];
}
LIBC_INLINE constexpr T &front() { return Data[0]; }
LIBC_INLINE constexpr const T &front() const { return Data[0]; }

LIBC_INLINE constexpr T &back() LIBC_LIFETIME_BOUND { return Data[N - 1]; }
LIBC_INLINE constexpr const T &back() const LIBC_LIFETIME_BOUND {
return Data[N - 1];
}
LIBC_INLINE constexpr T &back() { return Data[N - 1]; }
LIBC_INLINE constexpr const T &back() const { return Data[N - 1]; }

LIBC_INLINE constexpr T &operator[](size_t Index) LIBC_LIFETIME_BOUND {
return Data[Index];
}
LIBC_INLINE constexpr T &operator[](size_t Index) { return Data[Index]; }

LIBC_INLINE constexpr const T &
operator[](size_t Index) const LIBC_LIFETIME_BOUND {
LIBC_INLINE constexpr const T &operator[](size_t Index) const {
return Data[Index];
}

Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/CPP/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ template <typename T> struct Atomic {
LIBC_INLINE void set(T rhs) { val = rhs; }
};

template <typename T> struct LIBC_GSL_POINTER AtomicRef {
template <typename T> struct AtomicRef {
static_assert(is_trivially_copyable_v<T> && is_copy_constructible_v<T> &&
is_move_constructible_v<T> && is_copy_assignable_v<T> &&
is_move_assignable_v<T>,
Expand Down
10 changes: 3 additions & 7 deletions libc/src/__support/CPP/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_MUTEX_H

#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
Expand All @@ -29,17 +28,14 @@ template <typename MutexType> class lock_guard {

public:
// Calls `m.lock()` upon resource acquisition.
LIBC_INLINE explicit lock_guard(LIBC_LIFETIME_BOUND MutexType &m) : mutex(m) {
mutex.lock();
}
explicit lock_guard(MutexType &m) : mutex(m) { mutex.lock(); }

// Acquires ownership of the mutex object `m` without attempting to lock
// it. The behavior is undefined if the current thread does not hold the
// lock on `m`. Does not call `m.lock()` upon resource acquisition.
LIBC_INLINE lock_guard(LIBC_LIFETIME_BOUND MutexType &m, adopt_lock_t /* t */)
: mutex(m) {}
lock_guard(MutexType &m, adopt_lock_t /* t */) : mutex(m) {}

LIBC_INLINE ~lock_guard() { mutex.unlock(); }
~lock_guard() { mutex.unlock(); }

// non-copyable
lock_guard &operator=(const lock_guard &) = delete;
Expand Down
12 changes: 4 additions & 8 deletions libc/src/__support/CPP/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,11 @@ template <typename T> class optional {

LIBC_INLINE constexpr void reset() { storage.reset(); }

LIBC_INLINE constexpr const T &value() const &LIBC_LIFETIME_BOUND {
LIBC_INLINE constexpr const T &value() const & {
return storage.stored_value;
}

LIBC_INLINE constexpr T &value() & LIBC_LIFETIME_BOUND {
return storage.stored_value;
}
LIBC_INLINE constexpr T &value() & { return storage.stored_value; }

LIBC_INLINE constexpr explicit operator bool() const {
return storage.in_use;
Expand All @@ -124,12 +122,10 @@ template <typename T> class optional {
return &storage.stored_value;
}
LIBC_INLINE constexpr T *operator->() { return &storage.stored_value; }
LIBC_INLINE constexpr const T &operator*() const &LIBC_LIFETIME_BOUND {
return storage.stored_value;
}
LIBC_INLINE constexpr T &operator*() & LIBC_LIFETIME_BOUND {
LIBC_INLINE constexpr const T &operator*() const & {
return storage.stored_value;
}
LIBC_INLINE constexpr T &operator*() & { return storage.stored_value; }

LIBC_INLINE constexpr T &&value() && { return move(storage.stored_value); }
LIBC_INLINE constexpr T &&operator*() && {
Expand Down
7 changes: 3 additions & 4 deletions libc/src/__support/CPP/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace cpp {
// - No implicit type conversion (e.g. Span<B>, initialized with As where A
// inherits from B),
// - No reverse iterators
template <typename T> class LIBC_GSL_POINTER span {
template <typename T> class span {
template <typename U>
LIBC_INLINE_VAR static constexpr bool is_const_view_v =
!cpp::is_const_v<U> && cpp::is_const_v<T> &&
Expand Down Expand Up @@ -64,12 +64,11 @@ template <typename T> class LIBC_GSL_POINTER span {

template <typename U, size_t N,
cpp::enable_if_t<is_compatible_v<U>, bool> = true>
LIBC_INLINE constexpr span(LIBC_LIFETIME_BOUND U (&arr)[N])
: span_data(arr), span_size(N) {}
LIBC_INLINE constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}

template <typename U, size_t N,
cpp::enable_if_t<is_compatible_v<U>, bool> = true>
LIBC_INLINE constexpr span(LIBC_LIFETIME_BOUND array<U, N> &arr)
LIBC_INLINE constexpr span(array<U, N> &arr)
: span_data(arr.data()), span_size(arr.size()) {}

template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
Expand Down
19 changes: 6 additions & 13 deletions libc/src/__support/CPP/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,23 +106,16 @@ class string {
LIBC_INLINE constexpr const char *end() const { return data() + size_; }
LIBC_INLINE char *end() { return data() + size_; }

LIBC_INLINE constexpr const char &front() const LIBC_LIFETIME_BOUND {
return data()[0];
}
LIBC_INLINE char &front() LIBC_LIFETIME_BOUND { return data()[0]; }
LIBC_INLINE constexpr const char &front() const { return data()[0]; }
LIBC_INLINE char &front() { return data()[0]; }

LIBC_INLINE constexpr const char &back() const LIBC_LIFETIME_BOUND {
return data()[size_ - 1];
}
LIBC_INLINE char &back() LIBC_LIFETIME_BOUND { return data()[size_ - 1]; }
LIBC_INLINE constexpr const char &back() const { return data()[size_ - 1]; }
LIBC_INLINE char &back() { return data()[size_ - 1]; }

LIBC_INLINE constexpr const char &
operator[](size_t index) const LIBC_LIFETIME_BOUND {
return data()[index];
}
LIBC_INLINE char &operator[](size_t index) LIBC_LIFETIME_BOUND {
LIBC_INLINE constexpr const char &operator[](size_t index) const {
return data()[index];
}
LIBC_INLINE char &operator[](size_t index) { return data()[index]; }

LIBC_INLINE const char *c_str() const { return data(); }

Expand Down
15 changes: 1 addition & 14 deletions libc/src/__support/CPP/string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace cpp {
// do the checks before invoking the methods.
//
// This class will be extended as needed in future.
class LIBC_GSL_POINTER string_view {
class string_view {
private:
const char *Data;
size_t Len;
Expand All @@ -44,15 +44,6 @@ class LIBC_GSL_POINTER string_view {
return static_cast<size_t>(End - Str);
}

template <size_t N>
LIBC_INLINE static constexpr size_t
bounded_length(LIBC_LIFETIME_BOUND const char (&Str)[N]) {
for (size_t i = 0; i < N; ++i)
if (Str[i] == '\0')
return i;
return N;
}

LIBC_INLINE bool equals(string_view Other) const {
return (Len == Other.Len &&
compareMemory(Data, Other.Data, Other.Len) == 0);
Expand Down Expand Up @@ -86,10 +77,6 @@ class LIBC_GSL_POINTER string_view {
LIBC_INLINE constexpr string_view(const char *Str, size_t N)
: Data(Str), Len(N) {}

template <size_t N>
LIBC_INLINE constexpr string_view(LIBC_LIFETIME_BOUND const char (&Str)[N])
: Data(Str), Len(bounded_length(Str)) {}

LIBC_INLINE constexpr const char *data() const { return Data; }

// Returns the size of the string_view.
Expand Down
4 changes: 1 addition & 3 deletions libc/src/__support/CPP/stringstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ class StringStream {
// null terminator was not explicitly written, then the return value
// will not include one. In order to produce a string_view to a null
// terminated string, write ENDS explicitly.
[[nodiscard]] LIBC_INLINE string_view str() const {
return string_view(data.data(), write_ptr);
}
string_view str() const { return string_view(data.data(), write_ptr); }

// Write the characters from |str| to the stream.
StringStream &operator<<(string_view str) {
Expand Down
6 changes: 2 additions & 4 deletions libc/src/__support/CPP/utility/forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ namespace cpp {

// forward
template <typename T>
LIBC_INLINE constexpr T &&
forward(LIBC_LIFETIME_BOUND remove_reference_t<T> &value) {
LIBC_INLINE constexpr T &&forward(remove_reference_t<T> &value) {
return static_cast<T &&>(value);
}

template <typename T>
LIBC_INLINE constexpr T &&
forward(LIBC_LIFETIME_BOUND remove_reference_t<T> &&value) {
LIBC_INLINE constexpr T &&forward(remove_reference_t<T> &&value) {
static_assert(!is_lvalue_reference_v<T>,
"cannot forward an rvalue as an lvalue");
return static_cast<T &&>(value);
Expand Down
3 changes: 1 addition & 2 deletions libc/src/__support/CPP/utility/move.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ namespace cpp {

// move
template <class T>
LIBC_INLINE constexpr cpp::remove_reference_t<T> &&
move(LIBC_LIFETIME_BOUND T &&t) {
LIBC_INLINE constexpr cpp::remove_reference_t<T> &&move(T &&t) {
return static_cast<typename cpp::remove_reference_t<T> &&>(t);
}

Expand Down
80 changes: 0 additions & 80 deletions libc/src/__support/macros/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,84 +91,4 @@ LIBC_THREAD_MODE_EXTERNAL.
#define LIBC_NO_SANITIZE_OOB_ACCESS
#endif

// LIBC_LIFETIME_BOUND indicates that a function parameter's lifetime is tied
// to the return value. This helps compilers detect use-after-free bugs.
//
// Example usage:
// const T &get_value(const Container &c LIBC_LIFETIME_BOUND,
/// const T &default_val LIBC_LIFETIME_BOUND);
// // Warns if temporary Container or default_val is bound to the result
//
// For member functions, apply after the function signature:
// const char *data() const LIBC_LIFETIME_BOUND;
// // The returned pointer should not outlive '*this'
#if __has_cpp_attribute(clang::lifetimebound)
#define LIBC_LIFETIME_BOUND [[clang::lifetimebound]]
#elif __has_cpp_attribute(msvc::lifetimebound)
#define LIBC_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif __has_cpp_attribute(lifetimebound)
#define LIBC_LIFETIME_BOUND [[lifetimebound]]
#else
#define LIBC_LIFETIME_BOUND
#endif

// LIBC_LIFETIME_CAPTURE_BY(X) indicates that parameter X captures/stores a
// reference to the annotated parameter. Warns if temporaries are passed.
//
// Example usage:
// void add_to_set(cpp::string_view a LIBC_LIFETIME_CAPTURE_BY(s),
// cpp::set<cpp::string_view>& s) {
// s.insert(a); // 's' now holds a reference to 'a'
// }
// // Warns: add_to_set(cpp::string(), s); // temporary captured by 's'
//
// X can be: another parameter name, 'this', 'global', or 'unknown'
// Multiple capturing entities: LIBC_LIFETIME_CAPTURE_BY(s1, s2)
//
// For member functions capturing 'this', apply after function signature:
// void capture_self(cpp::set<S*>& s) LIBC_LIFETIME_CAPTURE_BY(s);
#if __has_cpp_attribute(clang::lifetime_capture_by)
#define LIBC_LIFETIME_CAPTURE_BY(X) [[clang::lifetime_capture_by(X)]]
#else
#define LIBC_LIFETIME_CAPTURE_BY(X)
#endif

// LIBC_GSL_POINTER marks a class as a "view" type that points to data owned
// elsewhere. Lifetime analysis treats it as potentially dangling when the
// owner is destroyed. Use for types like string_view, span, or custom views.
//
// Example usage:
// class LIBC_GSL_POINTER StringView {
// const char *data_;
// public:
// StringView(const String& s); // Points into 's'
// };
// // Warns: StringView sv = String(); // sv points to destroyed temporary
//
// The attribute takes an optional type parameter (e.g., [[gsl::Pointer(int)]])
// but it's typically omitted in libc usage.
#if __has_cpp_attribute(gsl::Pointer)
#define LIBC_GSL_POINTER [[gsl::Pointer]]
#else
#define LIBC_GSL_POINTER
#endif

// LIBC_GSL_OWNER marks a class as owning the data it manages. When an Owner
// is destroyed, any Pointer constructed from it becomes dangling.
//
// Example usage:
// class LIBC_GSL_OWNER String {
// char *data_;
// public:
// ~String() { delete[] data_; }
// };
//
// Relationship: LIBC_GSL_POINTER types "point into" LIBC_GSL_OWNER types.
// When the owner dies, pointers derived from it are considered dangling.
#if __has_cpp_attribute(gsl::Owner)
#define LIBC_GSL_OWNER [[gsl::Owner]]
#else
#define LIBC_GSL_OWNER
#endif

#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
Loading