EricWF created this revision.
EricWF added a reviewer: mclow.lists.
EricWF added a subscriber: cfe-commits.

This patch uses `diagnose_if` to attempt to catch null inputs in `std::string`. 
Note that unlike `__attribute__((non_null))` `diagnose_if` does not affect 
codegen.


https://reviews.llvm.org/D28716

Files:
  include/string
  test/libcxx/strings/diagnose_null_pointer.fail.cpp

Index: test/libcxx/strings/diagnose_null_pointer.fail.cpp
===================================================================
--- /dev/null
+++ test/libcxx/strings/diagnose_null_pointer.fail.cpp
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: diagnose-if-support, verify-support
+
+// Test that libc++ generates a warning diagnostic when the container is
+// provided a non-const callable comparator.
+
+#include <string>
+#include <memory>
+
+void test_constructors() {
+#if 0 // FIXME: Add diagnose_if to string constructors
+  std::string s1(nullptr); // expected-warning 1+ {{cannot construct string from a null pointer}}
+  std::string s2(nullptr, std::allocator<char>()); // expected-warning 1+ {{cannot construct string from a null pointer}}
+  std::string s3(nullptr, 0);
+  std::string s4(nullptr, 1); // expected-warning 1+ {{cannot construct string from a null pointer}}
+  std::string s5(nullptr, 0, std::allocator<char>());
+  std::string s6(nullptr, 1, std::allocator<char>()); // expected-warning 1+ {{cannot construct string from a null pointer}}
+#endif
+}
+
+void test_assignment() {
+  std::string s1;
+  s1 = nullptr; // expected-warning 1+ {{pointer cannot be null}}
+  s1.assign(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+  s1.assign(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_append() {
+  std::string s;
+  s.append(nullptr, 0);
+  s.append(nullptr, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.append(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_insert() {
+  std::string s;
+  s.insert(0, nullptr, 0); // OK
+  s.insert(0, nullptr, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.insert(0, nullptr); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_replace() {
+  std::string s;
+  s.replace(0, 0, nullptr, 0);
+  s.replace(0, 0, nullptr, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.replace(0, 0, nullptr); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_find() {
+  std::string s;
+  s.find(nullptr, 0, 0);
+  s.find(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.find(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_rfind() {
+  std::string s;
+  s.rfind(nullptr, 0, 0);
+  s.rfind(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.rfind(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_find_first_of() {
+  std::string s;
+  s.find_first_of(nullptr, 0, 0);
+  s.find_first_of(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.find_first_of(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_find_last_of() {
+  std::string s;
+  s.find_last_of(nullptr, 0, 0);
+  s.find_last_of(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.find_last_of(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+
+void test_find_first_not_of() {
+  std::string s;
+  s.find_first_not_of(nullptr, 0, 0);
+  s.find_first_not_of(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.find_first_not_of(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_find_last_not_of() {
+  std::string s;
+  s.find_last_not_of(nullptr, 0, 0);
+  s.find_last_not_of(nullptr, 0, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.find_last_not_of(nullptr, 0); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+void test_compare() {
+  std::string s;
+  s.compare(0, 0, nullptr, 0);
+  s.compare(0, 0, nullptr, 1); // expected-warning 1+ {{pointer cannot be null}}
+  s.compare(0, 0, nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  s.compare(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wunused-comparison"
+#endif
+
+void test_comparison_operators() {
+  std::string s;
+  s == static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) == s; // expected-warning 1+ {{pointer cannot be null}}
+  s != static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) != s; // expected-warning 1+ {{pointer cannot be null}}
+  s < static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) < s; // expected-warning 1+ {{pointer cannot be null}}
+  s <= static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) <= s; // expected-warning 1+ {{pointer cannot be null}}
+  s > static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) > s; // expected-warning 1+ {{pointer cannot be null}}
+  s >= static_cast<char const*>(nullptr); // expected-warning 1+ {{pointer cannot be null}}
+  static_cast<char const*>(nullptr) >= s; // expected-warning 1+ {{pointer cannot be null}}
+}
+
+int main() {
+  test_constructors();
+  test_assignment();
+  test_append();
+  test_insert();
+  test_replace();
+  test_find();
+  test_rfind();
+  test_find_first_of();
+  test_find_last_of();
+  test_find_first_not_of();
+  test_find_last_not_of();
+  test_compare();
+  test_comparison_operators();
+}
Index: include/string
===================================================================
--- include/string
+++ include/string
@@ -825,7 +825,9 @@
     basic_string& operator=(basic_string&& __str)
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 #endif
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s)
+      _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
+    {return assign(__s);}
     basic_string& operator=(value_type __c);
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
@@ -1539,6 +1541,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
 {
+    // FIXME: Add _LIBCPP_DIAGNOSE_WARNING
     _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
     __init(__s, traits_type::length(__s));
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1548,9 +1551,11 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s,
+                                                        const allocator_type& __a)
     : __r_(__a)
 {
+    // FIXME: Add _LIBCPP_DIAGNOSE_WARNING
     _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
     __init(__s, traits_type::length(__s));
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1560,8 +1565,10 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s,
+                                                        size_type __n)
 {
+    // FIXME: Add _LIBCPP_DIAGNOSE_WARNING
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
     __init(__s, __n);
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1571,7 +1578,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s,
+                                                        size_type __n,
+                                                        const allocator_type& __a)
     : __r_(__a)
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
@@ -1733,7 +1742,7 @@
     __init(__sv.data(), __sv.size());
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
-#endif	
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1940,6 +1949,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
     size_type __cap = capacity();
@@ -2127,6 +2137,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
     return assign(__s, traits_type::length(__s));
@@ -2137,6 +2148,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
     size_type __cap = capacity();
@@ -2243,7 +2255,7 @@
             const basic_string __temp (__first, __last, __alloc());
             append(__temp.data(), __temp.size());
         }
-        else 
+        else
         {
             if (__cap - __sz < __n)
                 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
@@ -2294,6 +2306,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
     return append(__s, traits_type::length(__s));
@@ -2303,7 +2316,10 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos,
+                                                  const value_type* __s,
+                                                  size_type __n)
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
     size_type __sz = size();
@@ -2471,6 +2487,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
     return insert(__pos, __s, traits_type::length(__s));
@@ -2521,7 +2538,11 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos,
+                                                   size_type __n1,
+                                                   const value_type* __s,
+                                                   size_type __n2)
+  _LIBCPP_DIAGNOSE_WARNING(__n2 > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
     size_type __sz = size();
@@ -2656,7 +2677,10 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos,
+                                                   size_type __n1,
+                                                   const value_type* __s)
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
     return replace(__pos, __n1, __s, traits_type::length(__s));
@@ -3033,6 +3057,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos,
                                                 size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
     return __str_find<value_type, size_type, traits_type, npos>
@@ -3064,6 +3089,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
     return __str_find<value_type, size_type, traits_type, npos>
@@ -3086,6 +3112,7 @@
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos,
                                                  size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
     return __str_rfind<value_type, size_type, traits_type, npos>
@@ -3117,6 +3144,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
     return __str_rfind<value_type, size_type, traits_type, npos>
@@ -3139,6 +3167,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos,
                                                          size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
     return __str_find_first_of<value_type, size_type, traits_type, npos>
@@ -3170,6 +3199,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
     return __str_find_first_of<value_type, size_type, traits_type, npos>
@@ -3192,6 +3222,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos,
                                                         size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
     return __str_find_last_of<value_type, size_type, traits_type, npos>
@@ -3223,6 +3254,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
     return __str_find_last_of<value_type, size_type, traits_type, npos>
@@ -3245,6 +3277,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos,
                                                              size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
     return __str_find_first_not_of<value_type, size_type, traits_type, npos>
@@ -3276,6 +3309,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
     return __str_find_first_not_of<value_type, size_type, traits_type, npos>
@@ -3299,6 +3333,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos,
                                                             size_type __n) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__n > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
     return __str_find_last_not_of<value_type, size_type, traits_type, npos>
@@ -3330,6 +3365,7 @@
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
     return __str_find_last_not_of<value_type, size_type, traits_type, npos>
@@ -3380,6 +3416,7 @@
                                                    size_type __n1,
                                                    const value_type* __s,
                                                    size_type __n2) const
+  _LIBCPP_DIAGNOSE_WARNING(__n2 > 0 && __s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
     size_type __sz = size();
@@ -3448,6 +3485,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
     return compare(0, npos, __s, traits_type::length(__s));
@@ -3458,6 +3496,7 @@
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
                                                    const value_type* __s) const
+  _LIBCPP_DIAGNOSE_WARNING(__s == nullptr, "pointer cannot be null")
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
     return compare(__pos1, __n1, __s, traits_type::length(__s));
@@ -3519,6 +3558,7 @@
 bool
 operator==(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     typedef basic_string<_CharT, _Traits, _Allocator> _String;
     _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
@@ -3532,6 +3572,7 @@
 bool
 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     typedef basic_string<_CharT, _Traits, _Allocator> _String;
     _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
@@ -3554,6 +3595,7 @@
 bool
 operator!=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     return !(__lhs == __rhs);
 }
@@ -3563,6 +3605,7 @@
 bool
 operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     return !(__lhs == __rhs);
 }
@@ -3583,6 +3626,7 @@
 bool
 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     return __lhs.compare(__rhs) < 0;
 }
@@ -3592,6 +3636,7 @@
 bool
 operator< (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     return __rhs.compare(__lhs) > 0;
 }
@@ -3612,6 +3657,7 @@
 bool
 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     return __rhs < __lhs;
 }
@@ -3621,6 +3667,7 @@
 bool
 operator> (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     return __rhs < __lhs;
 }
@@ -3641,6 +3688,7 @@
 bool
 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     return !(__rhs < __lhs);
 }
@@ -3650,6 +3698,7 @@
 bool
 operator<=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     return !(__rhs < __lhs);
 }
@@ -3670,6 +3719,7 @@
 bool
 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__rhs == nullptr, "pointer cannot be null")
 {
     return !(__lhs < __rhs);
 }
@@ -3679,6 +3729,7 @@
 bool
 operator>=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+  _LIBCPP_DIAGNOSE_WARNING(__lhs == nullptr, "pointer cannot be null")
 {
     return !(__lhs < __rhs);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to