[libc++] Diagnose passing null pointers to a bunch of APIs (#148585)
This commit is contained in:
parent
baf2953097
commit
b5348e7622
@ -33,6 +33,7 @@ AttributeMacros: [
|
|||||||
'_LIBCPP_DEPRECATED_IN_CXX20',
|
'_LIBCPP_DEPRECATED_IN_CXX20',
|
||||||
'_LIBCPP_DEPRECATED_IN_CXX23',
|
'_LIBCPP_DEPRECATED_IN_CXX23',
|
||||||
'_LIBCPP_DEPRECATED',
|
'_LIBCPP_DEPRECATED',
|
||||||
|
'_LIBCPP_DIAGNOSE_NULLPTR_IF',
|
||||||
'_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION',
|
'_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION',
|
||||||
'_LIBCPP_EXPORTED_FROM_ABI',
|
'_LIBCPP_EXPORTED_FROM_ABI',
|
||||||
'_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS',
|
'_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS',
|
||||||
|
@ -1081,6 +1081,20 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_DIAGNOSE_WARNING(...)
|
# define _LIBCPP_DIAGNOSE_WARNING(...)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_APPLE_CLANG_VER) && \
|
||||||
|
(!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER >= 2001)
|
||||||
|
# define _LIBCPP_DIAGNOSE_IF(...) __attribute__((__diagnose_if__(__VA_ARGS__)))
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_DIAGNOSE_IF(...)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define _LIBCPP_DIAGNOSE_NULLPTR_IF(condition, condition_description) \
|
||||||
|
_LIBCPP_DIAGNOSE_IF( \
|
||||||
|
condition, \
|
||||||
|
"null passed to callee that requires a non-null argument" condition_description, \
|
||||||
|
"warning", \
|
||||||
|
"nonnull")
|
||||||
|
|
||||||
# if __has_cpp_attribute(_Clang::__lifetimebound__)
|
# if __has_cpp_attribute(_Clang::__lifetimebound__)
|
||||||
# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
|
# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
|
||||||
# else
|
# else
|
||||||
|
@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
|
template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
|
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __location, _Args&&... __args) {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at");
|
_LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at");
|
||||||
return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
|
return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
@ -73,13 +73,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_at(_Tp* __loc) {
|
|||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
|
|
||||||
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
|
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* __loc) {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __loc) {
|
||||||
std::__destroy_at(__loc);
|
std::__destroy_at(__loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if _LIBCPP_STD_VER >= 20
|
# if _LIBCPP_STD_VER >= 20
|
||||||
template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
|
template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void destroy_at(_Tp* __loc) {
|
_LIBCPP_HIDE_FROM_ABI constexpr void destroy_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __loc) {
|
||||||
std::__destroy_at(__loc);
|
std::__destroy_at(__loc);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
@ -329,7 +329,8 @@ __vprint_unicode([[maybe_unused]] FILE* __stream,
|
|||||||
} // namespace __print
|
} // namespace __print
|
||||||
|
|
||||||
template <class... _Args>
|
template <class... _Args>
|
||||||
_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
|
_LIBCPP_HIDE_FROM_ABI void
|
||||||
|
print(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||||
# if _LIBCPP_HAS_UNICODE
|
# if _LIBCPP_HAS_UNICODE
|
||||||
if constexpr (__print::__use_unicode_execution_charset)
|
if constexpr (__print::__use_unicode_execution_charset)
|
||||||
__print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
|
__print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
|
||||||
@ -346,7 +347,8 @@ _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Args>
|
template <class... _Args>
|
||||||
_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
|
_LIBCPP_HIDE_FROM_ABI void
|
||||||
|
println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||||
# if _LIBCPP_HAS_UNICODE
|
# if _LIBCPP_HAS_UNICODE
|
||||||
// Note the wording in the Standard is inefficient. The output of
|
// Note the wording in the Standard is inefficient. The output of
|
||||||
// std::format is a std::string which is then copied. This solution
|
// std::format is a std::string which is then copied. This solution
|
||||||
@ -361,7 +363,7 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
||||||
_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) {
|
_LIBCPP_HIDE_FROM_ABI inline void println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream) {
|
||||||
std::print(__stream, "\n");
|
std::print(__stream, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,7 +379,8 @@ _LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __a
|
|||||||
|
|
||||||
# if _LIBCPP_HAS_UNICODE
|
# if _LIBCPP_HAS_UNICODE
|
||||||
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
||||||
_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
|
_LIBCPP_HIDE_FROM_ABI inline void
|
||||||
|
vprint_unicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
|
||||||
__print::__vprint_unicode(__stream, __fmt, __args, false);
|
__print::__vprint_unicode(__stream, __fmt, __args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +392,8 @@ _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args
|
|||||||
# endif // _LIBCPP_HAS_UNICODE
|
# endif // _LIBCPP_HAS_UNICODE
|
||||||
|
|
||||||
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
|
||||||
_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
|
_LIBCPP_HIDE_FROM_ABI inline void
|
||||||
|
vprint_nonunicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
|
||||||
__print::__vprint_nonunicode(__stream, __fmt, __args, false);
|
__print::__vprint_nonunicode(__stream, __fmt, __args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,13 +1065,15 @@ public:
|
|||||||
basic_string(nullptr_t) = delete;
|
basic_string(nullptr_t) = delete;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
|
||||||
__init(__s, __n);
|
__init(__s, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||||
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
|
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero")
|
||||||
: __alloc_(__a) {
|
: __alloc_(__a) {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
|
||||||
__init(__s, __n);
|
__init(__s, __n);
|
||||||
@ -1394,7 +1396,8 @@ public:
|
|||||||
return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
|
return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n)
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
|
||||||
|
|
||||||
@ -1521,8 +1524,9 @@ public:
|
|||||||
return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
|
return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n)
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
|
||||||
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
|
||||||
|
|
||||||
template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
|
template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
|
||||||
@ -1593,7 +1597,8 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
||||||
insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
|
insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n)
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
|
||||||
@ -1673,8 +1678,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
||||||
replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
|
replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
|
||||||
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
||||||
|
replace(size_type __pos, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
||||||
@ -1783,7 +1790,8 @@ public:
|
|||||||
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
|
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
|
||||||
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -1814,7 +1822,8 @@ public:
|
|||||||
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
|
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
|
||||||
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -1847,7 +1856,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
||||||
find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
|
||||||
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -1881,7 +1891,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
||||||
find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
|
||||||
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -1915,7 +1926,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
||||||
find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
|
||||||
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -1949,7 +1961,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
|
||||||
find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
|
||||||
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
@ -2026,7 +2039,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 int
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 int
|
||||||
compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
|
compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
|
||||||
|
|
||||||
// starts_with
|
// starts_with
|
||||||
|
|
||||||
@ -3564,7 +3578,8 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
|
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
|
||||||
operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
|
operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||||||
|
const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __rhs) _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
|
||||||
|
|
||||||
using _String = basic_string<_CharT, _Traits, _Allocator>;
|
using _String = basic_string<_CharT, _Traits, _Allocator>;
|
||||||
|
@ -318,8 +318,8 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
|
_LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
|
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
|
||||||
: __data_(__s),
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero")
|
||||||
__size_(__len) {
|
: __data_(__s), __size_(__len) {
|
||||||
# if _LIBCPP_STD_VER >= 14
|
# if _LIBCPP_STD_VER >= 14
|
||||||
// Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
|
// Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
|
||||||
// range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
|
// range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
|
||||||
@ -352,7 +352,7 @@ public:
|
|||||||
: __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
|
: __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
|
||||||
# endif // _LIBCPP_STD_VER >= 23
|
# endif // _LIBCPP_STD_VER >= 23
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s)
|
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s)
|
||||||
: __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
|
: __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
|
||||||
|
|
||||||
# if _LIBCPP_STD_VER >= 23
|
# if _LIBCPP_STD_VER >= 23
|
||||||
@ -483,17 +483,19 @@ public:
|
|||||||
return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
|
return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* __s) const _NOEXCEPT {
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
|
||||||
|
compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
|
||||||
return compare(basic_string_view(__s));
|
return compare(basic_string_view(__s));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
|
||||||
compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
|
compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
|
||||||
return substr(__pos1, __n1).compare(basic_string_view(__s));
|
return substr(__pos1, __n1).compare(basic_string_view(__s));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
|
||||||
compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const {
|
compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") {
|
||||||
return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
|
return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,13 +511,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
|
||||||
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
|
find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
|
||||||
return std::__str_find<value_type, size_type, traits_type, npos>(
|
return std::__str_find<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -534,13 +537,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
|
||||||
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
rfind(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
|
rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
|
||||||
return std::__str_rfind<value_type, size_type, traits_type, npos>(
|
return std::__str_rfind<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -560,13 +564,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
|
||||||
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_first_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
|
find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
|
||||||
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
|
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -586,13 +591,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
|
||||||
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_last_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
|
find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
|
||||||
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
|
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -613,13 +619,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
|
||||||
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_first_not_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
|
find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
|
||||||
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
|
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -640,13 +647,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
|
find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
|
||||||
|
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
|
||||||
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
|
||||||
find_last_not_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
|
find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
|
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
|
||||||
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
|
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
|
||||||
data(), size(), __s, __pos, traits_type::length(__s));
|
data(), size(), __s, __pos, traits_type::length(__s));
|
||||||
@ -661,7 +669,7 @@ public:
|
|||||||
return !empty() && _Traits::eq(front(), __c);
|
return !empty() && _Traits::eq(front(), __c);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept {
|
constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
|
||||||
return starts_with(basic_string_view(__s));
|
return starts_with(basic_string_view(__s));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,7 +681,7 @@ public:
|
|||||||
return !empty() && _Traits::eq(back(), __c);
|
return !empty() && _Traits::eq(back(), __c);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept {
|
constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
|
||||||
return ends_with(basic_string_view(__s));
|
return ends_with(basic_string_view(__s));
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
@ -683,7 +691,9 @@ public:
|
|||||||
|
|
||||||
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
|
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
|
||||||
|
|
||||||
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return find(__s) != npos; }
|
constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
|
||||||
|
return find(__s) != npos;
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03, c++11, c++14
|
||||||
|
|
||||||
|
// Ensure that APIs which take a pointer are diagnosing passing a nullptr to them
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
using Arr = int[1];
|
||||||
|
int* const np = nullptr;
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 20
|
||||||
|
Arr* const np2 = nullptr;
|
||||||
|
std::construct_at(np); // expected-warning {{null passed}}
|
||||||
|
std::destroy_at(np2); // expected-warning {{null passed}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::destroy_at(np); // expected-warning {{null passed}}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: libcpp-has-no-unicode
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
|
||||||
|
|
||||||
|
// Ensure that APIs which take a FILE* are diagnosing passing a nullptr to them
|
||||||
|
|
||||||
|
#include <print>
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
std::print(nullptr, ""); // expected-warning {{null passed}}
|
||||||
|
std::println(nullptr, ""); // expected-warning {{null passed}}
|
||||||
|
std::println(nullptr); // expected-warning {{null passed}}
|
||||||
|
std::vprint_unicode(nullptr, "", std::make_format_args()); // expected-warning {{null passed}}
|
||||||
|
std::vprint_nonunicode(nullptr, "", std::make_format_args()); // expected-warning {{null passed}}
|
||||||
|
}
|
@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
// UNSUPPORTED: c++03
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
// Ensure that APIs which take a CharT* (and no size for it) are diagnosing passing a nullptr to them
|
// Ensure that APIs which take a CharT* are diagnosing passing a nullptr to them
|
||||||
|
|
||||||
|
// Clang 19 and AppleClang don't have diagnose_if with diagnostic flags
|
||||||
|
// UNSUPPORTED: clang-19, apple-clang-17
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -20,6 +23,7 @@ void func() {
|
|||||||
std::string str2(np, std::allocator<char>{}); // expected-warning {{null passed}}
|
std::string str2(np, std::allocator<char>{}); // expected-warning {{null passed}}
|
||||||
str2 = np; // expected-warning {{null passed}}
|
str2 = np; // expected-warning {{null passed}}
|
||||||
str2 += np; // expected-warning {{null passed}}
|
str2 += np; // expected-warning {{null passed}}
|
||||||
|
str2.assign(np); // expected-warning {{null passed}}
|
||||||
str2.append(np); // expected-warning {{null passed}}
|
str2.append(np); // expected-warning {{null passed}}
|
||||||
str2.insert(0, np); // expected-warning {{null passed}}
|
str2.insert(0, np); // expected-warning {{null passed}}
|
||||||
str2.find(np); // expected-warning {{null passed}}
|
str2.find(np); // expected-warning {{null passed}}
|
||||||
@ -30,6 +34,8 @@ void func() {
|
|||||||
str2.find_last_not_of(np); // expected-warning {{null passed}}
|
str2.find_last_not_of(np); // expected-warning {{null passed}}
|
||||||
str2.compare(np); // expected-warning {{null passed}}
|
str2.compare(np); // expected-warning {{null passed}}
|
||||||
str2.compare(0, 0, np); // expected-warning {{null passed}}
|
str2.compare(0, 0, np); // expected-warning {{null passed}}
|
||||||
|
str2.replace(0, 0, np); // expected-warning {{null passed}}
|
||||||
|
(void)(str2 == np); // expected-warning {{null passed}}
|
||||||
|
|
||||||
#if TEST_STD_VER >= 20
|
#if TEST_STD_VER >= 20
|
||||||
str2.starts_with(np); // expected-warning {{null passed}}
|
str2.starts_with(np); // expected-warning {{null passed}}
|
||||||
@ -38,4 +44,21 @@ void func() {
|
|||||||
#if TEST_STD_VER >= 23
|
#if TEST_STD_VER >= 23
|
||||||
str2.contains(np); // expected-warning {{null passed}}
|
str2.contains(np); // expected-warning {{null passed}}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// These diagnostics are issued via diagnose_if, so we want to check the full description
|
||||||
|
std::string str3(nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
std::string str4(nullptr, 1, std::allocator<char>{}); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.find(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.rfind(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.find_first_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.find_last_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.find_first_not_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.find_last_not_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.compare(0, 0, nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n2 is not zero}}
|
||||||
|
str4.assign(nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.append(nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.insert(0, nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str4.replace(0, 0, nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n2 is not zero}}
|
||||||
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
// Construct a string_view from a null pointer
|
// Construct a string_view from a null pointer
|
||||||
// constexpr basic_string_view( const CharT* s );
|
// constexpr basic_string_view( const CharT* s );
|
||||||
|
|
||||||
|
// We're testing for assertions here, so let's not diagnose the misuses at compile time
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-nonnull
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "check_assertion.h"
|
#include "check_assertion.h"
|
||||||
|
53
libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp
Normal file
53
libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
// Ensure that APIs which take a CharT* are diagnosing passing a nullptr to them
|
||||||
|
|
||||||
|
// Clang 19 and AppleClang don't have diagnose_if with diagnostic flags
|
||||||
|
// UNSUPPORTED: clang-19, apple-clang-17
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
const char* const np = nullptr;
|
||||||
|
std::string_view str1(np); // expected-warning {{null passed}}
|
||||||
|
str1 = np; // expected-warning {{null passed}}
|
||||||
|
str1.find(np); // expected-warning {{null passed}}
|
||||||
|
str1.rfind(np); // expected-warning {{null passed}}
|
||||||
|
str1.find_first_of(np); // expected-warning {{null passed}}
|
||||||
|
str1.find_last_of(np); // expected-warning {{null passed}}
|
||||||
|
str1.find_first_not_of(np); // expected-warning {{null passed}}
|
||||||
|
str1.find_last_not_of(np); // expected-warning {{null passed}}
|
||||||
|
str1.compare(np); // expected-warning {{null passed}}
|
||||||
|
str1.compare(0, 0, np); // expected-warning {{null passed}}
|
||||||
|
(void)(str1 == np); // expected-warning {{null passed}}
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 20
|
||||||
|
str1.starts_with(np); // expected-warning {{null passed}}
|
||||||
|
str1.ends_with(np); // expected-warning {{null passed}}
|
||||||
|
#endif
|
||||||
|
#if TEST_STD_VER >= 23
|
||||||
|
str1.contains(np); // expected-warning {{null passed}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// These diagnostics are issued via diagnose_if, so we want to check the full description
|
||||||
|
std::string_view str2(nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if len is not zero}}
|
||||||
|
str2.find(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.rfind(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.find_first_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.find_last_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.find_first_not_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.find_last_not_of(nullptr, 0, 1); // expected-warning {{null passed to callee that requires a non-null argument if n is not zero}}
|
||||||
|
str2.compare(0, 0, nullptr, 1); // expected-warning {{null passed to callee that requires a non-null argument if n2 is not zero}}
|
||||||
|
// clang-format on
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user