CJ-Johnson updated this revision to Diff 385532.
CJ-Johnson added a comment.

Rebase on head


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113148/new/

https://reviews.llvm.org/D113148

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-stringview-nullptr.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-stringview-nullptr.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-stringview-nullptr.cpp
@@ -0,0 +1,1221 @@
+// RUN: %check_clang_tidy %s bugprone-stringview-nullptr -std=c++17 %t
+
+namespace std {
+
+using nullptr_t = decltype(nullptr);
+
+template <typename T>
+T &&declval();
+
+template <typename T>
+struct type_identity { using type = T; };
+template <typename T>
+using type_identity_t = typename type_identity<T>::type;
+
+template <typename C>
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const C *);
+  basic_string_view(const basic_string_view &);
+  basic_string_view &operator=(const basic_string_view &);
+};
+
+template <typename C>
+bool operator<(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator<(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator<(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+template <typename C>
+bool operator<=(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator<=(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator<=(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+template <typename C>
+bool operator>(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator>(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator>(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+template <typename C>
+bool operator>=(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator>=(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator>=(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+template <typename C>
+bool operator==(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator==(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator==(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+template <typename C>
+bool operator!=(basic_string_view<C>, basic_string_view<C>);
+template <typename C>
+bool operator!=(type_identity_t<basic_string_view<C>>, basic_string_view<C>);
+template <typename C>
+bool operator!=(basic_string_view<C>, type_identity_t<basic_string_view<C>>);
+
+using string_view = basic_string_view<char>;
+
+} // namespace std
+
+void function(std::string_view);
+void function(std::string_view, std::string_view);
+
+void temporary_construction() /* a */ {
+  // Functional Cast
+  {
+    (void)(std::string_view(nullptr)) /* a1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+    // CHECK-FIXES: {{^}}    (void)(std::string_view()) /* a1 */;
+
+    (void)(std::string_view((nullptr))) /* a2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view()) /* a2 */;
+
+    (void)(std::string_view({nullptr})) /* a3 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view()) /* a3 */;
+
+    (void)(std::string_view({(nullptr)})) /* a4 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view()) /* a4 */;
+
+    (void)(std::string_view({})) /* a5 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view()) /* a5 */;
+
+    // (void)(const std::string_view(nullptr)) /* a6 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view((nullptr))) /* a7 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view({nullptr})) /* a8 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view({(nullptr)})) /* a9 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view({})) /* a10 */; // Default `const CharT*`
+    // CV qualifiers do not compile in this context
+  }
+
+  // Temporary Object
+  {
+    (void)(std::string_view{nullptr}) /* a11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view{}) /* a11 */;
+
+    (void)(std::string_view{(nullptr)}) /* a12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view{}) /* a12 */;
+
+    (void)(std::string_view{{nullptr}}) /* a13 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view{}) /* a13 */;
+
+    (void)(std::string_view{{(nullptr)}}) /* a14 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view{}) /* a14 */;
+
+    (void)(std::string_view{{}}) /* a15 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(std::string_view{}) /* a15 */;
+
+    // (void)(const std::string_view{nullptr}) /* a16 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view{(nullptr)}) /* a17 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view{{nullptr}}) /* a18 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view{{(nullptr)}}) /* a19 */;
+    // CV qualifiers do not compile in this context
+
+    // (void)(const std::string_view{{}}) /* a20 */; // Default `const CharT*`
+    // CV qualifiers do not compile in this context
+  }
+
+  // C-Style Cast && Compound Literal
+  {
+    (void)((std::string_view) nullptr) /* a21 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view) {}) /* a21 */;
+
+    (void)((std::string_view)(nullptr)) /* a22 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a22 */;
+
+    (void)((std::string_view){nullptr}) /* a23 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a23 */;
+
+    (void)((std::string_view){(nullptr)}) /* a24 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a24 */;
+
+    (void)((std::string_view){{nullptr}}) /* a25 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a25 */;
+
+    (void)((std::string_view){{(nullptr)}}) /* a26 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a26 */;
+
+    (void)((std::string_view){{}}) /* a27 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((std::string_view){}) /* a27 */;
+
+    (void)((const std::string_view) nullptr) /* a28 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view) {}) /* a28 */;
+
+    (void)((const std::string_view)(nullptr)) /* a29 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a29 */;
+
+    (void)((const std::string_view){nullptr}) /* a30 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a30 */;
+
+    (void)((const std::string_view){(nullptr)}) /* a31 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a31 */;
+
+    (void)((const std::string_view){{nullptr}}) /* a32 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a32 */;
+
+    (void)((const std::string_view){{(nullptr)}}) /* a33 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a33 */;
+
+    (void)((const std::string_view){{}}) /* a34 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)((const std::string_view){}) /* a34 */;
+  }
+
+  // Static Cast
+  {
+    (void)(static_cast<std::string_view>(nullptr)) /* a35 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(static_cast<std::string_view>(std::string_view())) /* a35 */;
+
+    (void)(static_cast<std::string_view>((nullptr))) /* a36 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(static_cast<std::string_view>(std::string_view())) /* a36 */;
+
+    // (void)(static_cast<std::string_view>({nullptr})) /* a37 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(static_cast<std::string_view>({(nullptr)})) /* a38 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(static_cast<std::string_view>({})) /* a39 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(static_cast<const std::string_view>(nullptr)) /* a40 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(static_cast<const std::string_view>(std::string_view())) /* a40 */;
+
+    (void)(static_cast<const std::string_view>((nullptr))) /* a41 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(static_cast<const std::string_view>(std::string_view())) /* a41 */;
+
+    // (void)(static_cast<const std::string_view>({nullptr})) /* a42 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(static_cast<const std::string_view>({(nullptr)})) /* a43 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(static_cast<const std::string_view>({})) /* a44 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void stack_construction() /* b */ {
+  // Copy Initialization
+  {
+    std::string_view b1 = nullptr;
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b1 = {};
+
+    std::string_view b2 = (nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b2 = {};
+
+    const std::string_view b3 = nullptr;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b3 = {};
+
+    const std::string_view b4 = (nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b4 = {};
+  }
+
+  // Copy List Initialization
+  {
+    std::string_view b5 = {nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b5 = {};
+
+    std::string_view b6 = {(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b6 = {};
+
+    std::string_view b7 = {{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b7 = {};
+
+    const std::string_view b8 = {nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b8 = {};
+
+    const std::string_view b9 = {(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b9 = {};
+
+    const std::string_view b10 = {{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b10 = {};
+  }
+
+  // Direct Initialization
+  {
+    std::string_view b11(nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b11;
+
+    std::string_view b12((nullptr));
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b12;
+
+    std::string_view b13({nullptr});
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b13;
+
+    std::string_view b14({(nullptr)});
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b14;
+
+    std::string_view b15({}); // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b15;
+
+    const std::string_view b16(nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b16;
+
+    const std::string_view b17((nullptr));
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b17;
+
+    const std::string_view b18({nullptr});
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b18;
+
+    const std::string_view b19({(nullptr)});
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b19;
+
+    const std::string_view b20({}); // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b20;
+  }
+
+  // Direct List Initialization
+  {
+    std::string_view b21{nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b21{};
+
+    std::string_view b22{(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b22{};
+
+    std::string_view b23{{nullptr}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b23{};
+
+    std::string_view b24{{(nullptr)}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b24{};
+
+    std::string_view b25{{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view b25{};
+
+    const std::string_view b26{nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b26{};
+
+    const std::string_view b27{(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b27{};
+
+    const std::string_view b28{{nullptr}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b28{};
+
+    const std::string_view b29{{(nullptr)}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b29{};
+
+    const std::string_view b30{{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view b30{};
+  }
+}
+
+void field_construction() /* c */ {
+  struct DefaultMemberInitializers {
+    void CopyInitialization();
+
+    std::string_view c1 = nullptr;
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c1 = {};
+
+    std::string_view c2 = (nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c2 = {};
+
+    const std::string_view c3 = nullptr;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c3 = {};
+
+    const std::string_view c4 = (nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c4 = {};
+
+    void CopyListInitialization();
+
+    std::string_view c5 = {nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c5 = {};
+
+    std::string_view c6 = {(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c6 = {};
+
+    std::string_view c7 = {{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c7 = {};
+
+    const std::string_view c8 = {nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c8 = {};
+
+    const std::string_view c9 = {(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c9 = {};
+
+    const std::string_view c10 = {{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c10 = {};
+
+    void DirectListInitialization();
+
+    std::string_view c11{nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c11{};
+
+    std::string_view c12{(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c12{};
+
+    std::string_view c13{{nullptr}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c13{};
+
+    std::string_view c14{{(nullptr)}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c14{};
+
+    std::string_view c15{{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    std::string_view c15{};
+
+    const std::string_view c16{nullptr};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c16{};
+
+    const std::string_view c17{(nullptr)};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c17{};
+
+    const std::string_view c18{{nullptr}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c18{};
+
+    const std::string_view c19{{(nullptr)}};
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c19{};
+
+    const std::string_view c20{{}}; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    const std::string_view c20{};
+  };
+
+  class ConstructorInitializers {
+    ConstructorInitializers()
+        : direct_initialization(),
+
+          c21(nullptr),
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c21(),
+
+          c22((nullptr)),
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c22(),
+
+          c23({nullptr}),
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c23(),
+
+          c24({(nullptr)}),
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c24(),
+
+          c25({}), // Default `const CharT*`
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c25(),
+
+          direct_list_initialization(),
+
+          c26{nullptr},
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c26{},
+
+          c27{(nullptr)},
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c27{},
+
+          c28{{nullptr}},
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c28{},
+
+          c29{{(nullptr)}},
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c29{},
+
+          c30{{}}, // Default `const CharT*`
+          // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+          // CHECK-FIXES: {{^}}          c30{},
+
+          end_of_list() {}
+
+    std::nullptr_t direct_initialization;
+    std::string_view c21;
+    std::string_view c22;
+    std::string_view c23;
+    std::string_view c24;
+    std::string_view c25;
+    std::nullptr_t direct_list_initialization;
+    std::string_view c26;
+    std::string_view c27;
+    std::string_view c28;
+    std::string_view c29;
+    std::string_view c30;
+    std::nullptr_t end_of_list;
+  };
+}
+
+void default_argument_construction() /* d */ {
+  // Copy Initialization
+  {
+    void d1(std::string_view sv = nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d1(std::string_view sv = {});
+
+    void d2(std::string_view sv = (nullptr));
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d2(std::string_view sv = {});
+
+    void d3(const std::string_view sv = nullptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d3(const std::string_view sv = {});
+
+    void d4(const std::string_view sv = (nullptr));
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d4(const std::string_view sv = {});
+  }
+
+  // Copy List Initialization
+  {
+    void d5(std::string_view sv = {nullptr});
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d5(std::string_view sv = {});
+
+    void d6(std::string_view sv = {(nullptr)});
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d6(std::string_view sv = {});
+
+    void d7(std::string_view sv = {{}}); // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d7(std::string_view sv = {});
+
+    void d8(const std::string_view sv = {nullptr});
+    // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d8(const std::string_view sv = {});
+
+    void d9(const std::string_view sv = {(nullptr)});
+    // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d9(const std::string_view sv = {});
+
+    void d10(const std::string_view sv = {{}}); // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    void d10(const std::string_view sv = {});
+  }
+}
+
+void heap_construction() /* e */ {
+  // Direct Initialization
+  {
+    (void)(new std::string_view(nullptr)) /* e1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view()) /* e1 */;
+
+    (void)(new std::string_view((nullptr))) /* e2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view()) /* e2 */;
+
+    (void)(new std::string_view({nullptr})) /* e3 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view()) /* e3 */;
+
+    (void)(new std::string_view({(nullptr)})) /* e4 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view()) /* e4 */;
+
+    (void)(new std::string_view({})) /* e5 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view()) /* e5 */;
+
+    (void)(new const std::string_view(nullptr)) /* e6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view()) /* e6 */;
+
+    (void)(new const std::string_view((nullptr))) /* e7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view()) /* e7 */;
+
+    (void)(new const std::string_view({nullptr})) /* e8 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view()) /* e8 */;
+
+    (void)(new const std::string_view({(nullptr)})) /* e9 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view()) /* e9 */;
+
+    (void)(new const std::string_view({})) /* e10 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view()) /* e10 */;
+  }
+
+  // Direct List Initialization
+  {
+    (void)(new std::string_view{nullptr}) /* e11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view{}) /* e11 */;
+
+    (void)(new std::string_view{(nullptr)}) /* e12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view{}) /* e12 */;
+
+    (void)(new std::string_view{{nullptr}}) /* e13 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view{}) /* e13 */;
+
+    (void)(new std::string_view{{(nullptr)}}) /* e14 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view{}) /* e14 */;
+
+    (void)(new std::string_view{{}}) /* e15 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new std::string_view{}) /* e15 */;
+
+    (void)(new const std::string_view{nullptr}) /* e16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view{}) /* e16 */;
+
+    (void)(new const std::string_view{(nullptr)}) /* e17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view{}) /* e17 */;
+
+    (void)(new const std::string_view{{nullptr}}) /* e18 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view{}) /* e18 */;
+
+    (void)(new const std::string_view{{(nullptr)}}) /* e19 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view{}) /* e19 */;
+
+    (void)(new const std::string_view{{}}) /* e20 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    (void)(new const std::string_view{}) /* e20 */;
+  }
+}
+
+void function_invocation() /* f */ {
+  // Single Argument
+  {
+    function(nullptr) /* f1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}) /* f1 */;
+
+    function((nullptr)) /* f2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}) /* f2 */;
+
+    function({nullptr}) /* f3 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}) /* f3 */;
+
+    function({(nullptr)}) /* f4 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}) /* f4 */;
+
+    function({{}}) /* f5 */; // Default `const CharT*`
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}) /* f5 */;
+  }
+
+  // Multiple Argument
+  {
+    function(nullptr, nullptr) /* f6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing{{.*}}default
+    // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}, {}) /* f6 */;
+
+    function((nullptr), (nullptr)) /* f7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing{{.*}}default
+    // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}, {}) /* f7 */;
+
+    function({nullptr}, {nullptr}) /* f8 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}, {}) /* f8 */;
+
+    function({(nullptr)}, {(nullptr)}) /* f9 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}, {}) /* f9 */;
+
+    function({{}}, {{}}) /* f10 */; // Default `const CharT*`s
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
+    // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: constructing{{.*}}default
+    // CHECK-FIXES: {{^}}    function({}, {}) /* f10 */;
+  }
+}
+
+void assignment(std::string_view sv) /* g */ {
+  sv = nullptr /* g1 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+  // CHECK-FIXES: {{^}}  sv = {} /* g1 */;
+
+  sv = (nullptr) /* g2 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  sv = {} /* g2 */;
+
+  sv = {nullptr} /* g3 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  sv = {} /* g3 */;
+
+  sv = {(nullptr)} /* g4 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  sv = {} /* g4 */;
+
+  sv = {{}} /* g5 */; // Default `const CharT*`
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  sv = {} /* g5 */;
+}
+
+void pointer_assignment(std::string_view *sv_ptr) /* h */ {
+  *sv_ptr = nullptr /* h1 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  *sv_ptr = {} /* h1 */;
+
+  *sv_ptr = (nullptr) /* h2 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  *sv_ptr = {} /* h2 */;
+
+  *sv_ptr = {nullptr} /* h3 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  *sv_ptr = {} /* h3 */;
+
+  *sv_ptr = {(nullptr)} /* h4 */;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  *sv_ptr = {} /* h4 */;
+
+  *sv_ptr = {{}} /* h5 */; // Default `const CharT*`
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment{{.*}}default
+  // CHECK-FIXES: {{^}}  *sv_ptr = {} /* h5 */;
+}
+
+void lesser_comparison(std::string_view sv) /* i */ {
+  // Without Equality
+  {
+    (void)(sv < nullptr) /* i1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: comparing basic_string_view to null is undefined; replace with the empty string
+    // CHECK-FIXES: {{^}}    (void)(sv < "") /* i1 */;
+
+    (void)(sv < (nullptr)) /* i2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv < "") /* i2 */;
+
+    // (void)(sv < {nullptr}) /* i3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv < {(nullptr)}) /* i4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv < {{}}) /* i5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr < sv) /* i6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" < sv) /* i6 */;
+
+    (void)((nullptr) < sv) /* i7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" < sv) /* i7 */;
+
+    // (void)({nullptr} < sv) /* i8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} < sv) /* i9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} < sv) /* i10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // With Equality
+  {
+    (void)(sv <= nullptr) /* i11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv <= "") /* i11 */;
+
+    (void)(sv <= (nullptr)) /* i12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv <= "") /* i12 */;
+
+    // (void)(sv <= {nullptr}) /* i13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv <= {(nullptr)}) /* i14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv <= {{}}) /* i15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr <= sv) /* i16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" <= sv) /* i16 */;
+
+    (void)((nullptr) <= sv) /* i17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" <= sv) /* i17 */;
+
+    // (void)({nullptr} <= sv) /* i18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} <= sv) /* i19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} <= sv) /* i20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void pointer_lesser_comparison(std::string_view *sv_ptr) /* j */ {
+  // Without Equality
+  {
+    (void)(*sv_ptr < nullptr) /* j1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr < "") /* j1 */;
+
+    (void)(*sv_ptr < (nullptr)) /* j2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr < "") /* j2 */;
+
+    // (void)(*sv_ptr < {nullptr}) /* j3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr < {(nullptr)}) /* j4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr < {{}}) /* j5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr < *sv_ptr) /* j6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" < *sv_ptr) /* j6 */;
+
+    (void)((nullptr) < *sv_ptr) /* j7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" < *sv_ptr) /* j7 */;
+
+    // (void)({nullptr} < *sv_ptr) /* j8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} < *sv_ptr) /* j9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} < *sv_ptr) /* j10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // With Equality
+  {
+    (void)(*sv_ptr <= nullptr) /* j11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr <= "") /* j11 */;
+
+    (void)(*sv_ptr <= (nullptr)) /* j12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr <= "") /* j12 */;
+
+    // (void)(*sv_ptr <= {nullptr}) /* j13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr <= {(nullptr)}) /* j14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr <= {{}}) /* j15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr <= *sv_ptr) /* j16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" <= *sv_ptr) /* j16 */;
+
+    (void)((nullptr) <= *sv_ptr) /* j17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" <= *sv_ptr) /* j17 */;
+
+    // (void)({nullptr} <= *sv_ptr) /* j18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} <= *sv_ptr) /* j19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} <= *sv_ptr) /* j20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void greater_comparison(std::string_view sv) /* k */ {
+  // Without Equality
+  {
+    (void)(sv > nullptr) /* k1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv > "") /* k1 */;
+
+    (void)(sv > (nullptr)) /* k2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv > "") /* k2 */;
+
+    // (void)(sv > {nullptr}) /* k3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv > {(nullptr)}) /* k4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv > {{}}) /* k5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr > sv) /* k6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" > sv) /* k6 */;
+
+    (void)((nullptr) > sv) /* k7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" > sv) /* k7 */;
+
+    // (void)({nullptr} > sv) /* k8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} > sv) /* k9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} > sv) /* k10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // With Equality
+  {
+    (void)(sv >= nullptr) /* k11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv >= "") /* k11 */;
+
+    (void)(sv >= (nullptr)) /* k12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(sv >= "") /* k12 */;
+
+    // (void)(sv >= {nullptr}) /* k13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv >= {(nullptr)}) /* k14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv >= {{}}) /* k15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr >= sv) /* k16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" >= sv) /* k16 */;
+
+    (void)((nullptr) >= sv) /* k17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" >= sv) /* k17 */;
+
+    // (void)({nullptr} >= sv) /* k18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} >= sv) /* k19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} >= sv) /* k20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void pointer_greater_comparison(std::string_view *sv_ptr) /* l */ {
+  // Without Equality
+  {
+    (void)(*sv_ptr > nullptr) /* l1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr > "") /* l1 */;
+
+    (void)(*sv_ptr > (nullptr)) /* l2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr > "") /* l2 */;
+
+    // (void)(*sv_ptr > {nullptr}) /* l3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr > {(nullptr)}) /* l4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr > {{}}) /* l5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr > *sv_ptr) /* l6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" > *sv_ptr) /* l6 */;
+
+    (void)((nullptr) > *sv_ptr) /* l7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" > *sv_ptr) /* l7 */;
+
+    // (void)({nullptr} > *sv_ptr) /* l8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} > *sv_ptr) /* l9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} > *sv_ptr) /* l10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // With Equality
+  {
+    (void)(*sv_ptr >= nullptr) /* l11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr >= "") /* l11 */;
+
+    (void)(*sv_ptr >= (nullptr)) /* l12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)(*sv_ptr >= "") /* l12 */;
+
+    // (void)(*sv_ptr >= {nullptr}) /* l13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr >= {(nullptr)}) /* l14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr >= {{}}) /* l15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr >= *sv_ptr) /* l16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" >= *sv_ptr) /* l16 */;
+
+    (void)((nullptr) >= *sv_ptr) /* l17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}empty string
+    // CHECK-FIXES: {{^}}    (void)("" >= *sv_ptr) /* l17 */;
+
+    // (void)({nullptr} >= *sv_ptr) /* l18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} >= *sv_ptr) /* l19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} >= *sv_ptr) /* l20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void equality_comparison(std::string_view sv) /* m */ {
+  // Empty
+  {
+    (void)(sv == nullptr) /* m1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv.empty()) /* m1 */;
+
+    (void)(sv == (nullptr)) /* m2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv.empty()) /* m2 */;
+
+    // (void)(sv == {nullptr}) /* m3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv == {(nullptr)}) /* m4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv == {{}}) /* m5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr == sv) /* m6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv.empty()) /* m6 */;
+
+    (void)((nullptr) == sv) /* m7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv.empty()) /* m7 */;
+
+    // (void)({nullptr} == sv) /* m8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} == sv) /* m9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} == sv) /* m10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // Non-Empty
+  {
+    (void)(sv != nullptr) /* m11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv.empty()) /* m11 */;
+
+    (void)(sv != (nullptr)) /* m12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv.empty()) /* m12 */;
+
+    // (void)(sv != {nullptr}) /* m13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv != {(nullptr)}) /* m14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(sv != {{}}) /* m15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr != sv) /* m16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv.empty()) /* m16 */;
+
+    (void)((nullptr) != sv) /* m17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv.empty()) /* m17 */;
+
+    // (void)({nullptr} != sv) /* m18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} != sv) /* m19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} != sv) /* m20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
+
+void pointer_equality_comparison(std::string_view *sv_ptr) /* n */ {
+  // Empty
+  {
+    (void)(*sv_ptr == nullptr) /* n1 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv_ptr->empty()) /* n1 */;
+
+    (void)(*sv_ptr == (nullptr)) /* n2 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv_ptr->empty()) /* n2 */;
+
+    // (void)(*sv_ptr == {nullptr}) /* n3 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr == {(nullptr)}) /* n4 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr == {{}}) /* n5 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr == *sv_ptr) /* n6 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv_ptr->empty()) /* n6 */;
+
+    (void)((nullptr) == *sv_ptr) /* n7 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(sv_ptr->empty()) /* n7 */;
+
+    // (void)({nullptr} == *sv_ptr) /* n8 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} == *sv_ptr) /* n9 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} == *sv_ptr) /* n10 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+
+  // Non-Empty
+  {
+    (void)(*sv_ptr != nullptr) /* n11 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv_ptr->empty()) /* n11 */;
+
+    (void)(*sv_ptr != (nullptr)) /* n12 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv_ptr->empty()) /* n12 */;
+
+    // (void)(*sv_ptr != {nullptr}) /* n13 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr != {(nullptr)}) /* n14 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)(*sv_ptr != {{}}) /* n15 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+
+    (void)(nullptr != *sv_ptr) /* n16 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv_ptr->empty()) /* n16 */;
+
+    (void)((nullptr) != *sv_ptr) /* n17 */;
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing{{.*}}emptiness query
+    // CHECK-FIXES: {{^}}    (void)(!sv_ptr->empty()) /* n17 */;
+
+    // (void)({nullptr} != *sv_ptr) /* n18 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({(nullptr)} != *sv_ptr) /* n19 */;
+    // Braced initializer list does not compile in this context
+
+    // (void)({{}} != *sv_ptr) /* n20 */; // Default `const CharT*`
+    // Braced initializer list does not compile in this context
+  }
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -92,6 +92,7 @@
    `bugprone-string-constructor <bugprone-string-constructor.html>`_, "Yes"
    `bugprone-string-integer-assignment <bugprone-string-integer-assignment.html>`_, "Yes"
    `bugprone-string-literal-with-embedded-nul <bugprone-string-literal-with-embedded-nul.html>`_,
+   `bugprone-stringview-nullptr <bugprone-stringview-nullptr.html>`_, "Yes"
    `bugprone-suspicious-enum-usage <bugprone-suspicious-enum-usage.html>`_,
    `bugprone-suspicious-include <bugprone-suspicious-include.html>`_,
    `bugprone-suspicious-memory-comparison <bugprone-suspicious-memory-comparison.html>`_,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst
@@ -0,0 +1,53 @@
+.. title:: clang-tidy - bugprone-stringview-nullptr
+
+bugprone-stringview-nullptr
+===========================
+
+Checks for various ways that the ``nullptr`` literal can be passed into the
+``const CharT*`` constructor of ``std::basic_string_view`` and replaces them
+with the default constructor in most cases. For the comparison operators,
+braced initializer list does not compile so instead the empty string is used.
+Also, ``==`` and ``!=`` are replaced with calls to ``.empty()``.
+
+This prevents code from invoking behavior which is unconditionally undefined.
+The single-argument ``const char*`` constructor of ``std::string_view`` does
+not check for the null case before dereferencing its input.
+
+.. code-block:: c++
+  std::string_view sv = nullptr;
+
+  sv = nullptr;
+
+  bool is_empty = sv == nullptr;
+  bool isnt_empty = sv != nullptr;
+
+  accepts_sv(nullptr);
+
+  accepts_sv({{}});  // A
+
+  accepts_sv({nullptr, 0});  // B
+
+is translated into...
+
+.. code-block:: c++
+  std::string_view sv = {};
+
+  sv = {};
+
+  bool is_empty = sv.empty();
+  bool isnt_empty = !sv.empty();
+
+  accepts_sv({});
+
+  accepts_sv({});  // A
+
+  accepts_sv({nullptr, 0});  // B
+
+Note: The source pattern with trailing comment "A" selects the
+``(const CharT*)`` constructor overload and then value-initializes the pointer,
+causing a null dereference. It happens to not include the ``nullptr`` literal,
+but it is still within the scope of this ClangTidy check.
+
+Note: The source pattern with trailing comment "B" selects the
+``(const CharT*, size_type)`` constructor which is perfectly valid, since the
+length argument is ``0``. It is not changed by this ClangTidy check.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -76,6 +76,19 @@
 New checks
 ^^^^^^^^^^
 
+- New :doc:`bugprone-stringview-nullptr
+  <clang-tidy/checks/bugprone-stringview-nullptr>` check.
+
+  Checks for various ways that the ``nullptr`` literal can be passed into the
+  ``const CharT*`` constructor of ``std::basic_string_view`` and replaces them
+  with the default constructor in most cases. For the comparison operators,
+  braced initializer list does not compile so instead the empty string is used.
+  Also, ``==`` and ``!=`` are replaced with calls to ``.empty()``.
+
+  This prevents code from invoking behavior which is unconditionally undefined.
+  The single-argument ``const char*`` constructor of ``std::string_view`` does
+  not check for the null case before dereferencing its input.
+
 - New :doc:`abseil-cleanup-ctad
   <clang-tidy/checks/abseil-cleanup-ctad>` check.
 
Index: clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h
@@ -0,0 +1,44 @@
+//===--- StringviewNullptrCheck.h - clang-tidy ------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGVIEWNULLPTRCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGVIEWNULLPTRCHECK_H
+
+#include "../utils/TransformerClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Checks for various ways that the `nullptr` literal can be passed into the
+/// `const CharT*` constructor of `std::basic_string_view` and replaces them
+/// with the default constructor in most cases. For the comparison operators,
+/// braced initializer list does not compile so instead the empty string is
+/// used. Also, `==` and `!=` are replaced with calls to `.empty()`.
+///
+/// This prevents code from invoking behavior which is unconditionally
+/// undefined. The single-argument `const char*` constructor of
+/// `std::string_view` does not check for the null case before dereferencing
+/// its input.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-stringview-nullptr.html
+class StringviewNullptrCheck : public utils::TransformerClangTidyCheck {
+public:
+  StringviewNullptrCheck(StringRef Name, ClangTidyContext *Context);
+
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus17;
+  }
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGVIEWNULLPTRCHECK_H
Index: clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp
@@ -0,0 +1,204 @@
+//===--- StringviewNullptrCheck.cpp - clang-tidy --------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "StringviewNullptrCheck.h"
+#include "../utils/TransformerClangTidyCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+using namespace ::clang::ast_matchers;
+using namespace ::clang::transformer;
+
+namespace {
+AST_MATCHER_P(InitListExpr, initCountIs, unsigned, N) {
+  return Node.getNumInits() == N;
+}
+} // namespace
+
+RewriteRule StringviewNullptrCheckImpl() {
+  auto construction_warning =
+      cat("constructing basic_string_view from null is undefined; replace with "
+          "the default constructor");
+  auto assignment_warning =
+      cat("assignment to basic_string_view from null is undefined; replace "
+          "with the default constructor");
+  auto relative_comparison_warning =
+      cat("comparing basic_string_view to null is undefined; replace with the "
+          "empty string");
+  auto equality_comparison_warning =
+      cat("comparing basic_string_view to null is undefined; replace with the "
+          "emptiness query");
+  auto StringViewConstructingFromNullptrExpr =
+      cxxConstructExpr(
+          hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+              cxxRecordDecl(hasName("std::basic_string_view")))))),
+          argumentCountIs(1), has(expr().bind("nullptr_argument_expr")),
+          hasArgument(
+              0, anyOf(ignoringParenImpCasts(cxxNullPtrLiteralExpr()),
+                       initListExpr(initCountIs(1),
+                                    hasInit(0, ignoringParenImpCasts(
+                                                   cxxNullPtrLiteralExpr()))),
+                       initListExpr(initCountIs(0)))))
+          .bind("construct_expr");
+
+  auto HandleTemporaryCXXFunctionalCastExpr = makeRule(
+      cxxFunctionalCastExpr(
+          hasSourceExpression(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleTemporaryCXXTemporaryObjectExpr = makeRule(
+      cxxTemporaryObjectExpr(StringViewConstructingFromNullptrExpr,
+                             unless(hasParent(compoundLiteralExpr()))),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleTemporaryCStyleCastExpr = makeRule(
+      cStyleCastExpr(
+          hasSourceExpression(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("{}")), construction_warning);
+
+  auto HandleTemporaryCompoundLiteralExpr = makeRule(
+      compoundLiteralExpr(has(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleTemporaryCXXStaticCastExpr = makeRule(
+      cxxStaticCastExpr(has(StringViewConstructingFromNullptrExpr),
+                        hasTypeLoc(typeLoc().bind("type_loc"))),
+      changeTo(node("nullptr_argument_expr"), cat(node("type_loc"), "()")),
+      construction_warning);
+
+  auto HandleStackCopyInitialization = makeRule(
+      declStmt(has(varDecl(has(implicitCastExpr(
+          ignoringImpCasts(StringViewConstructingFromNullptrExpr)))))),
+      changeTo(node("nullptr_argument_expr"), cat("{}")), construction_warning);
+
+  auto HandleStackDirectInitialization = makeRule(
+      declStmt(
+          has(varDecl(has(StringViewConstructingFromNullptrExpr),
+                      unless(has(cxxConstructExpr(isListInitialization()))))
+                  .bind("var_decl"))),
+      changeTo(node("construct_expr"), cat(name("var_decl"))),
+      construction_warning);
+
+  auto HandleStackDirectListAndCopyListInitialization = makeRule(
+      declStmt(has(varDecl(has(StringViewConstructingFromNullptrExpr),
+                           has(cxxConstructExpr(isListInitialization()))))),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleFieldCopyInitialization = makeRule(
+      fieldDecl(has(implicitCastExpr(
+          ignoringImpCasts(StringViewConstructingFromNullptrExpr)))),
+      changeTo(node("nullptr_argument_expr"), cat("{}")), construction_warning);
+
+  auto HandleFieldOtherInitialization = makeRule(
+      fieldDecl(has(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleConstructorInitialization = makeRule(
+      cxxCtorInitializer(
+          withInitializer(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleDefaultArgumentInitialization = makeRule(
+      parmVarDecl(hasInitializer(
+          implicitCastExpr(has(StringViewConstructingFromNullptrExpr)))),
+      changeTo(node("nullptr_argument_expr"), cat("{}")), construction_warning);
+
+  auto HandleDefaultArgumentListInitialization = makeRule(
+      parmVarDecl(hasInitializer(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleHeapInitialization = makeRule(
+      cxxNewExpr(has(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleFunctionArgumentInitialization = makeRule(
+      expr(hasParent(callExpr(unless(cxxOperatorCallExpr()))),
+           implicitCastExpr(has(StringViewConstructingFromNullptrExpr))),
+      changeTo(node("nullptr_argument_expr"), cat("{}")), construction_warning);
+
+  auto HandleFunctionArgumentListInitialization = makeRule(
+      expr(hasParent(callExpr(unless(cxxOperatorCallExpr()))),
+           StringViewConstructingFromNullptrExpr),
+      changeTo(node("nullptr_argument_expr"), cat("")), construction_warning);
+
+  auto HandleAssignment = makeRule(
+      materializeTemporaryExpr(
+          hasParent(cxxOperatorCallExpr(hasOverloadedOperatorName("="))),
+          has(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("construct_expr"), cat("{}")), assignment_warning);
+
+  auto HandleRelativeComparison = makeRule(
+      implicitCastExpr(hasParent(cxxOperatorCallExpr(
+                           hasAnyOverloadedOperatorName("<", "<=", ">", ">="))),
+                       has(StringViewConstructingFromNullptrExpr)),
+      changeTo(node("nullptr_argument_expr"), cat("\"\"")),
+      relative_comparison_warning);
+
+  auto HandleEmptyEqualityComparison = makeRule(
+      cxxOperatorCallExpr(
+          hasOverloadedOperatorName("=="),
+          hasOperands(
+              traverse(clang::TK_IgnoreUnlessSpelledInSource,
+                       expr().bind("string_view_instance")),
+              implicitCastExpr(has(StringViewConstructingFromNullptrExpr))))
+          .bind("root"),
+      changeTo(node("root"),
+               cat(access("string_view_instance", cat("empty")), "()")),
+      equality_comparison_warning);
+
+  auto HandleNonEmptyEqualityComparison = makeRule(
+      cxxOperatorCallExpr(
+          hasOverloadedOperatorName("!="),
+          hasOperands(
+              traverse(clang::TK_IgnoreUnlessSpelledInSource,
+                       expr().bind("string_view_instance")),
+              implicitCastExpr(has(StringViewConstructingFromNullptrExpr))))
+          .bind("root"),
+      changeTo(node("root"),
+               cat("!", access("string_view_instance", cat("empty")), "()")),
+      equality_comparison_warning);
+
+  return applyFirst({HandleTemporaryCXXFunctionalCastExpr,
+                     HandleTemporaryCXXTemporaryObjectExpr,
+                     HandleTemporaryCStyleCastExpr,
+                     HandleTemporaryCompoundLiteralExpr,
+                     HandleTemporaryCXXStaticCastExpr,
+                     HandleStackCopyInitialization,
+                     HandleStackDirectInitialization,
+                     HandleStackDirectListAndCopyListInitialization,
+                     HandleFieldCopyInitialization,
+                     HandleFieldOtherInitialization,
+                     HandleConstructorInitialization,
+                     HandleDefaultArgumentInitialization,
+                     HandleDefaultArgumentListInitialization,
+                     HandleHeapInitialization,
+                     HandleFunctionArgumentInitialization,
+                     HandleFunctionArgumentListInitialization,
+                     HandleAssignment,
+                     HandleRelativeComparison,
+                     HandleEmptyEqualityComparison,
+                     HandleNonEmptyEqualityComparison});
+}
+
+StringviewNullptrCheck::StringviewNullptrCheck(StringRef Name,
+                                               ClangTidyContext *Context)
+    : utils::TransformerClangTidyCheck(StringviewNullptrCheckImpl(), Name,
+                                       Context) {}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -45,6 +45,7 @@
   StringConstructorCheck.cpp
   StringIntegerAssignmentCheck.cpp
   StringLiteralWithEmbeddedNulCheck.cpp
+  StringviewNullptrCheck.cpp
   SuspiciousEnumUsageCheck.cpp
   SuspiciousIncludeCheck.cpp
   SuspiciousMemoryComparisonCheck.cpp
Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -50,6 +50,7 @@
 #include "StringConstructorCheck.h"
 #include "StringIntegerAssignmentCheck.h"
 #include "StringLiteralWithEmbeddedNulCheck.h"
+#include "StringviewNullptrCheck.h"
 #include "SuspiciousEnumUsageCheck.h"
 #include "SuspiciousIncludeCheck.h"
 #include "SuspiciousMemoryComparisonCheck.h"
@@ -157,6 +158,8 @@
         "bugprone-string-integer-assignment");
     CheckFactories.registerCheck<StringLiteralWithEmbeddedNulCheck>(
         "bugprone-string-literal-with-embedded-nul");
+    CheckFactories.registerCheck<StringviewNullptrCheck>(
+        "bugprone-stringview-nullptr");
     CheckFactories.registerCheck<SuspiciousEnumUsageCheck>(
         "bugprone-suspicious-enum-usage");
     CheckFactories.registerCheck<SuspiciousIncludeCheck>(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to