CJ-Johnson updated this revision to Diff 384881.
CJ-Johnson marked an inline comment as done.
CJ-Johnson added a comment.
Fix spelling error
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,1030 @@
+// 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 basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(std::string_view()) /* a2 */;{{$}}
+
+ (void)(std::string_view({nullptr})) /* a3 */;
+ // 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()) /* a3 */;{{$}}
+
+ (void)(std::string_view({(nullptr)})) /* a4 */;
+ // 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()) /* a4 */;{{$}}
+
+ // (void)(const std::string_view(nullptr)) /* a5 */;
+ // CV qualifiers do not compile in this context
+
+ // (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
+ }
+
+ // Temporary Object
+ {
+ (void)(std::string_view{nullptr}) /* a9 */;
+ // 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{}) /* a9 */;{{$}}
+
+ (void)(std::string_view{(nullptr)}) /* a10 */;
+ // 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{}) /* a10 */;{{$}}
+
+ (void)(std::string_view{{nullptr}}) /* a11 */;
+ // 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{}) /* a11 */;{{$}}
+
+ (void)(std::string_view{{(nullptr)}}) /* a12 */;
+ // 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{}) /* a12 */;{{$}}
+
+ // (void)(const std::string_view{nullptr}) /* a13 */;
+ // CV qualifiers do not compile in this context
+
+ // (void)(const std::string_view{(nullptr)}) /* a14 */;
+ // CV qualifiers do not compile in this context
+
+ // (void)(const std::string_view{{nullptr}}) /* a15 */;
+ // CV qualifiers do not compile in this context
+
+ // (void)(const std::string_view{{(nullptr)}}) /* a16 */;
+ // CV qualifiers do not compile in this context
+ }
+
+ // C-Style Cast && Compound Literal
+ {
+ (void)((std::string_view) nullptr) /* a17 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view) {}) /* a17 */;{{$}}
+
+ (void)((std::string_view)(nullptr)) /* a18 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view){}) /* a18 */;{{$}}
+
+ (void)((std::string_view){nullptr}) /* a19 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view){}) /* a19 */;{{$}}
+
+ (void)((std::string_view){(nullptr)}) /* a20 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view){}) /* a20 */;{{$}}
+
+ (void)((std::string_view){{nullptr}}) /* a21 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view){}) /* a21 */;{{$}}
+
+ (void)((std::string_view){{(nullptr)}}) /* a22 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((std::string_view){}) /* a22 */;{{$}}
+
+ (void)((const std::string_view) nullptr) /* a23 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view) {}) /* a23 */;{{$}}
+
+ (void)((const std::string_view)(nullptr)) /* a24 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view){}) /* a24 */;{{$}}
+
+ (void)((const std::string_view){nullptr}) /* a25 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view){}) /* a25 */;{{$}}
+
+ (void)((const std::string_view){(nullptr)}) /* a26 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view){}) /* a26 */;{{$}}
+
+ (void)((const std::string_view){{nullptr}}) /* a27 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view){}) /* a27 */;{{$}}
+
+ (void)((const std::string_view){{(nullptr)}}) /* a28 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)((const std::string_view){}) /* a28 */;{{$}}
+ }
+
+ // Static Cast
+ {
+ (void)(static_cast<std::string_view>(nullptr)) /* a29 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(static_cast<std::string_view>(std::string_view{})) /* a29 */;{{$}}
+
+ (void)(static_cast<std::string_view>((nullptr))) /* a30 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(static_cast<std::string_view>(std::string_view{})) /* a30 */;{{$}}
+
+ // (void)(static_cast<std::string_view>({nullptr})) /* a31 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(static_cast<std::string_view>({(nullptr)})) /* a32 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(static_cast<const std::string_view>(nullptr)) /* a33 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(static_cast<const std::string_view>(std::string_view{})) /* a33 */;{{$}}
+
+ (void)(static_cast<const std::string_view>((nullptr))) /* a34 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(static_cast<const std::string_view>(std::string_view{})) /* a34 */;{{$}}
+
+ // (void)(static_cast<const std::string_view>({nullptr})) /* a35 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(static_cast<const std::string_view>({(nullptr)})) /* a36 */;
+ // 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 basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b1 = {};{{$}}
+
+ std::string_view b2 = (nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b2 = {};{{$}}
+
+ const std::string_view b3 = nullptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b3 = {};{{$}}
+
+ const std::string_view b4 = (nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b4 = {};{{$}}
+ }
+
+ // Copy List Initialization
+ {
+ std::string_view b5 = {nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b5 = { {} };{{$}}
+
+ std::string_view b6 = {(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b6 = { {} };{{$}}
+
+ const std::string_view b7 = {nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b7 = { {} };{{$}}
+
+ const std::string_view b8 = {(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b8 = { {} };{{$}}
+ }
+
+ // Direct Initialization
+ {
+ std::string_view b9(nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b9( {} );{{$}}
+
+ std::string_view b10((nullptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b10( {} );{{$}}
+
+ std::string_view b11({nullptr});
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b11( {} );{{$}}
+
+ std::string_view b12({(nullptr)});
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b12( {} );{{$}}
+
+ const std::string_view b13(nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b13( {} );{{$}}
+
+ const std::string_view b14((nullptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b14( {} );{{$}}
+
+ const std::string_view b15({nullptr});
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b15( {} );{{$}}
+
+ const std::string_view b16({(nullptr)});
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b16( {} );{{$}}
+ }
+
+ // Direct List Initialization
+ {
+ std::string_view b17{nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b17{ {} };{{$}}
+
+ std::string_view b18{(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b18{ {} };{{$}}
+
+ std::string_view b19{{nullptr}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b19{ {} };{{$}}
+
+ std::string_view b20{{(nullptr)}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view b20{ {} };{{$}}
+
+ const std::string_view b21{nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b21{ {} };{{$}}
+
+ const std::string_view b22{(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b22{ {} };{{$}}
+
+ const std::string_view b23{{nullptr}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b23{ {} };{{$}}
+
+ const std::string_view b24{{(nullptr)}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view b24{ {} };{{$}}
+ }
+}
+
+void field_construction() /* c */ {
+ struct DefaultMemberInitializers {
+ void CopyInitialization();
+
+ std::string_view c1 = nullptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c1 = {};{{$}}
+
+ std::string_view c2 = (nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c2 = {};{{$}}
+
+ const std::string_view c3 = nullptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c3 = {};{{$}}
+
+ const std::string_view c4 = (nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c4 = {};{{$}}
+
+ void CopyListInitialization();
+
+ std::string_view c5 = {nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c5 = {};{{$}}
+
+ std::string_view c6 = {(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c6 = {};{{$}}
+
+ const std::string_view c7 = {nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c7 = {};{{$}}
+
+ const std::string_view c8 = {(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c8 = {};{{$}}
+
+ void DirectListInitialization();
+
+ std::string_view c9{nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c9{};{{$}}
+
+ std::string_view c10{(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c10{};{{$}}
+
+ std::string_view c11{{nullptr}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c11{};{{$}}
+
+ std::string_view c12{{(nullptr)}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} std::string_view c12{};{{$}}
+
+ const std::string_view c13{nullptr};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c13{};{{$}}
+
+ const std::string_view c14{(nullptr)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c14{};{{$}}
+
+ const std::string_view c15{{nullptr}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c15{};{{$}}
+
+ const std::string_view c16{{(nullptr)}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} const std::string_view c16{};{{$}}
+ };
+
+ class ConstructorInitializers {
+ ConstructorInitializers()
+ : direct_initialization(),
+
+ c17(nullptr),
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c17(),{{$}}
+
+ c18((nullptr)),
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c18(),{{$}}
+
+ c19({nullptr}),
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c19(),{{$}}
+
+ c20({(nullptr)}),
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c20(),{{$}}
+
+ direct_list_initialization(),
+
+ c21{nullptr},
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c21{},{{$}}
+
+ c22{(nullptr)},
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c22{},{{$}}
+
+ c23{{nullptr}},
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c23{},{{$}}
+
+ c24{{(nullptr)}},
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} c24{},{{$}}
+
+ end_of_list() {}
+
+ std::nullptr_t direct_initialization;
+ std::string_view c17;
+ std::string_view c18;
+ std::string_view c19;
+ std::string_view c20;
+ std::nullptr_t direct_list_initialization;
+ std::string_view c21;
+ std::string_view c22;
+ std::string_view c23;
+ std::string_view c24;
+ 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 basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d1(std::string_view sv = {});{{$}}
+
+ void d2(std::string_view sv = (nullptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d2(std::string_view sv = {});{{$}}
+
+ void d3(const std::string_view sv = nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d3(const std::string_view sv = {});{{$}}
+
+ void d4(const std::string_view sv = (nullptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // 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 basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d5(std::string_view sv = {});{{$}}
+
+ void d6(std::string_view sv = {(nullptr)});
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d6(std::string_view sv = {});{{$}}
+
+ void d7(const std::string_view sv = {nullptr});
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d7(const std::string_view sv = {});{{$}}
+
+ void d8(const std::string_view sv = {(nullptr)});
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} void d8(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 basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view()) /* e1 */;{{$}}
+
+ (void)(new std::string_view((nullptr))) /* e2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view()) /* e2 */;{{$}}
+
+ (void)(new std::string_view({nullptr})) /* e3 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view()) /* e3 */;{{$}}
+
+ (void)(new std::string_view({(nullptr)})) /* e4 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view()) /* e4 */;{{$}}
+
+ (void)(new const std::string_view(nullptr)) /* e5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view()) /* e5 */;{{$}}
+
+ (void)(new const std::string_view((nullptr))) /* e6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view()) /* e6 */;{{$}}
+
+ (void)(new const std::string_view({nullptr})) /* e7 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view()) /* e7 */;{{$}}
+
+ (void)(new const std::string_view({(nullptr)})) /* e8 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view()) /* e8 */;{{$}}
+ }
+
+ // Direct List Initialization
+ {
+ (void)(new std::string_view{nullptr}) /* e9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view{}) /* e9 */;{{$}}
+
+ (void)(new std::string_view{(nullptr)}) /* e10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view{}) /* e10 */;{{$}}
+
+ (void)(new std::string_view{{nullptr}}) /* e11 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view{}) /* e11 */;{{$}}
+
+ (void)(new std::string_view{{(nullptr)}}) /* e12 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new std::string_view{}) /* e12 */;{{$}}
+
+ (void)(new const std::string_view{nullptr}) /* e13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view{}) /* e13 */;{{$}}
+
+ (void)(new const std::string_view{(nullptr)}) /* e14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view{}) /* e14 */;{{$}}
+
+ (void)(new const std::string_view{{nullptr}}) /* e15 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view{}) /* e15 */;{{$}}
+
+ (void)(new const std::string_view{{(nullptr)}}) /* e16 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} (void)(new const std::string_view{}) /* e16 */;{{$}}
+ }
+}
+
+void function_invocation() /* f */ {
+ // Single Argument
+ {
+ function(nullptr) /* f1 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}) /* f1 */;{{$}}
+
+ function((nullptr)) /* f2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}) /* f2 */;{{$}}
+
+ function({nullptr}) /* f3 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}) /* f3 */;{{$}}
+
+ function({(nullptr)}) /* f4 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}) /* f4 */;{{$}}
+ }
+
+ // Multiple Argument
+ {
+ function(nullptr, nullptr) /* f5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}, {}) /* f5 */;{{$}}
+
+ function((nullptr), (nullptr)) /* f6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}, {}) /* f6 */;{{$}}
+
+ function({nullptr}, {nullptr}) /* f7 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}, {}) /* f7 */;{{$}}
+
+ function({(nullptr)}, {(nullptr)}) /* f8 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: constructing basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} function({}, {}) /* f8 */;{{$}}
+ }
+}
+
+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 to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} sv = {} /* g2 */;{{$}}
+
+ sv = {nullptr} /* g3 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} sv = {} /* g3 */;{{$}}
+
+ sv = {(nullptr)} /* g4 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} sv = {} /* g4 */;{{$}}
+}
+
+void pointer_assignment(std::string_view *sv_ptr) /* h */ {
+ *sv_ptr = nullptr /* h1 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} *sv_ptr = {} /* h1 */;{{$}}
+
+ *sv_ptr = (nullptr) /* h2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} *sv_ptr = {} /* h2 */;{{$}}
+
+ *sv_ptr = {nullptr} /* h3 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} *sv_ptr = {} /* h3 */;{{$}}
+
+ *sv_ptr = {(nullptr)} /* h4 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: assignment to basic_string_view from null is undefined; replace with the default constructor
+ // CHECK-FIXES: {{^}} *sv_ptr = {} /* h4 */;{{$}}
+}
+
+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 basic_string_view to null is undefined; replace with the 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)(nullptr < sv) /* i5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" < sv) /* i5 */;{{$}}
+
+ (void)((nullptr) < sv) /* i6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" < sv) /* i6 */;{{$}}
+
+ // (void)({nullptr} < sv) /* i7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} < sv) /* i8*/;
+ // Braced initializer list does not compile in this context
+ }
+
+ // With Equality
+ {
+ (void)(sv <= nullptr) /* i9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(sv <= "") /* i9 */;{{$}}
+
+ (void)(sv <= (nullptr)) /* i10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(sv <= "") /* i10 */;{{$}}
+
+ // (void)(sv <= {nullptr}) /* i11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(sv <= {(nullptr)}) /* i12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr <= sv) /* i13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" <= sv) /* i13 */;{{$}}
+
+ (void)((nullptr) <= sv) /* i14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" <= sv) /* i14 */;{{$}}
+
+ // (void)({nullptr} <= sv) /* i15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} <= sv) /* i16 */;
+ // 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 basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr < "") /* j1 */;{{$}}
+
+ (void)(*sv_ptr < (nullptr)) /* j2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing basic_string_view to null is undefined; replace with the 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)(nullptr < *sv_ptr) /* j5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" < *sv_ptr) /* j5 */;{{$}}
+
+ (void)((nullptr) < *sv_ptr) /* j6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" < *sv_ptr) /* j6 */;{{$}}
+
+ // (void)({nullptr} < *sv_ptr) /* j7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} < *sv_ptr) /* j8 */;
+ // Braced initializer list does not compile in this context
+ }
+
+ // With Equality
+ {
+ (void)(*sv_ptr <= nullptr) /* j9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr <= "") /* j9 */;{{$}}
+
+ (void)(*sv_ptr <= (nullptr)) /* j10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr <= "") /* j10 */;{{$}}
+
+ // (void)(*sv_ptr <= {nullptr}) /* j11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(*sv_ptr <= {(nullptr)}) /* j12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr <= *sv_ptr) /* j13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" <= *sv_ptr) /* j13 */;{{$}}
+
+ (void)((nullptr) <= *sv_ptr) /* j14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" <= *sv_ptr) /* j14 */;{{$}}
+
+ // (void)({nullptr} <= *sv_ptr) /* j15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} <= *sv_ptr) /* j16 */;
+ // 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 basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(sv > "") /* k1 */;{{$}}
+
+ (void)(sv > (nullptr)) /* k2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: comparing basic_string_view to null is undefined; replace with the 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)(nullptr > sv) /* k5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" > sv) /* k5 */;{{$}}
+
+ (void)((nullptr) > sv) /* k6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" > sv) /* k6 */;{{$}}
+
+ // (void)({nullptr} > sv) /* k7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} > sv) /* k8 */;
+ // Braced initializer list does not compile in this context
+ }
+
+ // With Equality
+ {
+ (void)(sv >= nullptr) /* k9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(sv >= "") /* k9 */;{{$}}
+
+ (void)(sv >= (nullptr)) /* k10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(sv >= "") /* k10 */;{{$}}
+
+ // (void)(sv >= {nullptr}) /* k11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(sv >= {(nullptr)}) /* k12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr >= sv) /* k13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" >= sv) /* k13 */;{{$}}
+
+ (void)((nullptr) >= sv) /* k14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" >= sv) /* k14 */;{{$}}
+
+ // (void)({nullptr} >= sv) /* k15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} >= sv) /* k16 */;
+ // 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 basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr > "") /* l1 */;{{$}}
+
+ (void)(*sv_ptr > (nullptr)) /* l2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: comparing basic_string_view to null is undefined; replace with the 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)(nullptr > *sv_ptr) /* l5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" > *sv_ptr) /* l5 */;{{$}}
+
+ (void)((nullptr) > *sv_ptr) /* l6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" > *sv_ptr) /* l6 */;{{$}}
+
+ // (void)({nullptr} > *sv_ptr) /* l7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} > *sv_ptr) /* l8 */;
+ // Braced initializer list does not compile in this context
+ }
+
+ // With Equality
+ {
+ (void)(*sv_ptr >= nullptr) /* l9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr >= "") /* l9 */;{{$}}
+
+ (void)(*sv_ptr >= (nullptr)) /* l10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)(*sv_ptr >= "") /* l10 */;{{$}}
+
+ // (void)(*sv_ptr >= {nullptr}) /* l11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(*sv_ptr >= {(nullptr)}) /* l12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr >= *sv_ptr) /* l13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" >= *sv_ptr) /* l13 */;{{$}}
+
+ (void)((nullptr) >= *sv_ptr) /* l14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the empty string
+ // CHECK-FIXES: {{^}} (void)("" >= *sv_ptr) /* l14 */;{{$}}
+
+ // (void)({nullptr} >= *sv_ptr) /* l15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} >= *sv_ptr) /* l16 */;
+ // 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 basic_string_view to null is undefined; replace with the 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)(nullptr == sv) /* m5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(sv.empty()) /* m5 */;{{$}}
+
+ (void)((nullptr) == sv) /* m6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(sv.empty()) /* m6 */;{{$}}
+
+ // (void)({nullptr} == sv) /* m7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} == sv) /* m8 */;
+ // Braced initializer list does not compile in this context
+ }
+
+ // Non-Empty
+ {
+ (void)(sv != nullptr) /* m9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv.empty()) /* m9 */;{{$}}
+
+ (void)(sv != (nullptr)) /* m10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv.empty()) /* m10 */;{{$}}
+
+ // (void)(sv != {nullptr}) /* m11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(sv != {(nullptr)}) /* m12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr != sv) /* m13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv.empty()) /* m13 */;{{$}}
+
+ (void)((nullptr) != sv) /* m14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv.empty()) /* m14 */;{{$}}
+
+ // (void)({nullptr} != sv) /* m15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} != sv) /* m16 */;
+ // 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 basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(sv_ptr->empty()) /* n1 */;{{$}}
+
+ (void)(*sv_ptr == (nullptr)) /* n2 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the 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)(nullptr == *sv_ptr) /* n5 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(sv_ptr->empty()) /* n5 */;{{$}}
+
+ (void)((nullptr) == *sv_ptr) /* n6 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(sv_ptr->empty()) /* n6 */;{{$}}
+
+ // (void)({nullptr} == *sv_ptr) /* n7 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} == *sv_ptr) /* n8 */;
+ // Braced initializer list does not compile in this context
+ }
+
+ // Non-Empty
+ {
+ (void)(*sv_ptr != nullptr) /* n9 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv_ptr->empty()) /* n9 */;{{$}}
+
+ (void)(*sv_ptr != (nullptr)) /* n10 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv_ptr->empty()) /* n10 */;{{$}}
+
+ // (void)(*sv_ptr != {nullptr}) /* n11 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)(*sv_ptr != {(nullptr)}) /* n12 */;
+ // Braced initializer list does not compile in this context
+
+ (void)(nullptr != *sv_ptr) /* n13 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv_ptr->empty()) /* n13 */;{{$}}
+
+ (void)((nullptr) != *sv_ptr) /* n14 */;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: comparing basic_string_view to null is undefined; replace with the emptiness query
+ // CHECK-FIXES: {{^}} (void)(!sv_ptr->empty()) /* n14 */;{{$}}
+
+ // (void)({nullptr} != *sv_ptr) /* n15 */;
+ // Braced initializer list does not compile in this context
+
+ // (void)({(nullptr)} != *sv_ptr) /* n16 */;
+ // 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
@@ -91,6 +91,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>`_,
`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>`_,
@@ -448,3 +449,4 @@
`hicpp-vararg <hicpp-vararg.html>`_, `cppcoreguidelines-pro-type-vararg <cppcoreguidelines-pro-type-vararg.html>`_,
`llvm-else-after-return <llvm-else-after-return.html>`_, `readability-else-after-return <readability-else-after-return.html>`_, "Yes"
`llvm-qualified-auto <llvm-qualified-auto.html>`_, `readability-qualified-auto <readability-qualified-auto.html>`_, "Yes"
+
\ No newline at end of file
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,42 @@
+.. 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 ``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({nullptr, 0}); // unchanged
+
+becomes
+
+.. code-block:: c++
+
+ std::string_view sv = {};
+
+ sv = {};
+
+ bool is_empty = sv.empty();
+ bool isnt_empty = !sv.empty();
+
+ accepts_sv({});
+
+ accepts_sv({nullptr, 0}); // unchanged
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -76,6 +76,15 @@
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 `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()`.
+
- New :doc:`bugprone-suspicious-memory-comparison
<clang-tidy/checks/bugprone-suspicious-memory-comparison>` check.
Index: clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h
@@ -0,0 +1,36 @@
+//===--- 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 `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()`.
+///
+/// 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;
+};
+
+} // 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,185 @@
+//===--- 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;
+
+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(hasInit(0, ignoringParenImpCasts(
+ cxxNullPtrLiteralExpr()))))))
+ .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 HandleStackDirectAndBracedInitialization = makeRule(
+ declStmt(has(varDecl(has(StringViewConstructingFromNullptrExpr)))),
+ 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, HandleStackDirectAndBracedInitialization,
+ HandleFieldCopyInitialization, HandleFieldOtherInitialization,
+ HandleConstructorInitialization, HandleDefaultArgumentInitialization,
+ HandleDefaultArgumentListInitialization, HandleHeapInitialization,
+ HandleFunctionArgumentInitialization,
+ HandleFunctionArgumentListInitialization, HandleAssignment,
+ HandleRelativeComparison, HandleEmptyEqualityComparison,
+ HandleNonEmptyEqualityComparison});
+}
+
+StringviewNullptrCheck::StringviewNullptrCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : utils::TransformerClangTidyCheck(StringviewNullptrCheckImpl(), Name,
+ Context) {}
+
+bool StringviewNullptrCheck::isLanguageVersionSupported(
+ const LangOptions &LangOpts) const {
+ return LangOpts.CPlusPlus17;
+}
+
+} // 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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits