diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/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( "bugprone-string-literal-with-embedded-nul"); + CheckFactories.registerCheck( + "bugprone-stringview-nullptr"); CheckFactories.registerCheck( "bugprone-suspicious-enum-usage"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/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 diff --git a/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h b/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.h @@ -0,0 +1,34 @@ +//===--- 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 { + +/// Finds `nullptr` literals being converted to `std::string_view` and replaces +/// them with empty string literals. Equality comparison is special-cased and +/// 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 diff --git a/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp new file mode 100644 --- /dev/null +++ b/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 HandleTemporaryCStyleCaseExpr = 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, HandleTemporaryCStyleCaseExpr, + 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 diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -73,6 +73,13 @@ New checks ^^^^^^^^^^ +- New :doc:`bugprone-stringview-nullptr + ` check. + + Finds ``nullptr`` literals being converted to ``std::string_view`` and + replaces them with empty string literals. Equality comparison is + special-cased and replaced with calls to ``.empty()``. + - New :doc:`bugprone-suspicious-memory-comparison ` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst new file mode 100644 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-stringview-nullptr.rst @@ -0,0 +1,40 @@ +.. title:: clang-tidy - bugprone-stringview-nullptr + +bugprone-stringview-nullptr +=========================== + +Finds ``nullptr`` literals being converted to ``std::string_view`` and replaces +them with empty string literals. Equality comparison is special-cased and +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 \ No newline at end of file diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -12,33 +12,33 @@ .. csv-table:: :header: "Name", "Offers fixes" - `abseil-duration-addition `_, "Yes" - `abseil-duration-comparison `_, "Yes" - `abseil-duration-conversion-cast `_, "Yes" - `abseil-duration-division `_, "Yes" - `abseil-duration-factory-float `_, "Yes" - `abseil-duration-factory-scale `_, "Yes" - `abseil-duration-subtraction `_, "Yes" - `abseil-duration-unnecessary-conversion `_, "Yes" - `abseil-faster-strsplit-delimiter `_, "Yes" + `abseil-duration-addition `_, + `abseil-duration-comparison `_, + `abseil-duration-conversion-cast `_, + `abseil-duration-division `_, + `abseil-duration-factory-float `_, + `abseil-duration-factory-scale `_, + `abseil-duration-subtraction `_, + `abseil-duration-unnecessary-conversion `_, + `abseil-faster-strsplit-delimiter `_, `abseil-no-internal-dependencies `_, `abseil-no-namespace `_, - `abseil-redundant-strcat-calls `_, "Yes" - `abseil-str-cat-append `_, "Yes" - `abseil-string-find-startswith `_, "Yes" - `abseil-string-find-str-contains `_, "Yes" - `abseil-time-comparison `_, "Yes" - `abseil-time-subtraction `_, "Yes" - `abseil-upgrade-duration-conversions `_, "Yes" + `abseil-redundant-strcat-calls `_, + `abseil-str-cat-append `_, + `abseil-string-find-startswith `_, + `abseil-string-find-str-contains `_, + `abseil-time-comparison `_, + `abseil-time-subtraction `_, + `abseil-upgrade-duration-conversions `_, `altera-id-dependent-backward-branch `_, `altera-kernel-name-restriction `_, `altera-single-work-item-barrier `_, - `altera-struct-pack-align `_, "Yes" + `altera-struct-pack-align `_, `altera-unroll-loops `_, - `android-cloexec-accept `_, "Yes" + `android-cloexec-accept `_, `android-cloexec-accept4 `_, - `android-cloexec-creat `_, "Yes" - `android-cloexec-dup `_, "Yes" + `android-cloexec-creat `_, + `android-cloexec-dup `_, `android-cloexec-epoll-create `_, `android-cloexec-epoll-create1 `_, `android-cloexec-fopen `_, @@ -46,17 +46,17 @@ `android-cloexec-inotify-init1 `_, `android-cloexec-memfd-create `_, `android-cloexec-open `_, - `android-cloexec-pipe `_, "Yes" + `android-cloexec-pipe `_, `android-cloexec-pipe2 `_, `android-cloexec-socket `_, `android-comparison-in-temp-failure-retry `_, - `boost-use-to-string `_, "Yes" - `bugprone-argument-comment `_, "Yes" + `boost-use-to-string `_, + `bugprone-argument-comment `_, `bugprone-assert-side-effect `_, `bugprone-bad-signal-to-kill-thread `_, - `bugprone-bool-pointer-implicit-conversion `_, "Yes" + `bugprone-bool-pointer-implicit-conversion `_, `bugprone-branch-clone `_, - `bugprone-copy-constructor-init `_, "Yes" + `bugprone-copy-constructor-init `_, `bugprone-dangling-handle `_, `bugprone-dynamic-static-initializers `_, `bugprone-easily-swappable-parameters `_, @@ -64,52 +64,53 @@ `bugprone-fold-init-type `_, `bugprone-forward-declaration-namespace `_, `bugprone-forwarding-reference-overload `_, - `bugprone-implicit-widening-of-multiplication-result `_, "Yes" - `bugprone-inaccurate-erase `_, "Yes" + `bugprone-implicit-widening-of-multiplication-result `_, + `bugprone-inaccurate-erase `_, `bugprone-incorrect-roundings `_, `bugprone-infinite-loop `_, `bugprone-integer-division `_, `bugprone-lambda-function-name `_, - `bugprone-macro-parentheses `_, "Yes" + `bugprone-macro-parentheses `_, `bugprone-macro-repeated-side-effects `_, - `bugprone-misplaced-operator-in-strlen-in-alloc `_, "Yes" - `bugprone-misplaced-pointer-arithmetic-in-alloc `_, "Yes" + `bugprone-misplaced-operator-in-strlen-in-alloc `_, + `bugprone-misplaced-pointer-arithmetic-in-alloc `_, `bugprone-misplaced-widening-cast `_, - `bugprone-move-forwarding-reference `_, "Yes" + `bugprone-move-forwarding-reference `_, `bugprone-multiple-statement-macro `_, `bugprone-no-escape `_, - `bugprone-not-null-terminated-result `_, "Yes" - `bugprone-parent-virtual-call `_, "Yes" - `bugprone-posix-return `_, "Yes" - `bugprone-redundant-branch-condition `_, "Yes" - `bugprone-reserved-identifier `_, "Yes" + `bugprone-not-null-terminated-result `_, + `bugprone-parent-virtual-call `_, + `bugprone-posix-return `_, + `bugprone-redundant-branch-condition `_, + `bugprone-reserved-identifier `_, `bugprone-signal-handler `_, `bugprone-signed-char-misuse `_, `bugprone-sizeof-container `_, `bugprone-sizeof-expression `_, `bugprone-spuriously-wake-up-functions `_, - `bugprone-string-constructor `_, "Yes" - `bugprone-string-integer-assignment `_, "Yes" + `bugprone-string-constructor `_, + `bugprone-string-integer-assignment `_, `bugprone-string-literal-with-embedded-nul `_, + `bugprone-stringview-nullptr `_, `bugprone-suspicious-enum-usage `_, `bugprone-suspicious-include `_, `bugprone-suspicious-memory-comparison `_, - `bugprone-suspicious-memset-usage `_, "Yes" + `bugprone-suspicious-memset-usage `_, `bugprone-suspicious-missing-comma `_, - `bugprone-suspicious-semicolon `_, "Yes" - `bugprone-suspicious-string-compare `_, "Yes" - `bugprone-swapped-arguments `_, "Yes" - `bugprone-terminating-continue `_, "Yes" + `bugprone-suspicious-semicolon `_, + `bugprone-suspicious-string-compare `_, + `bugprone-swapped-arguments `_, + `bugprone-terminating-continue `_, `bugprone-throw-keyword-missing `_, `bugprone-too-small-loop-variable `_, `bugprone-undefined-memory-manipulation `_, `bugprone-undelegated-constructor `_, `bugprone-unhandled-exception-at-new `_, `bugprone-unhandled-self-assignment `_, - `bugprone-unused-raii `_, "Yes" + `bugprone-unused-raii `_, `bugprone-unused-return-value `_, `bugprone-use-after-move `_, - `bugprone-virtual-near-miss `_, "Yes" + `bugprone-virtual-near-miss `_, `cert-dcl21-cpp `_, `cert-dcl50-cpp `_, `cert-dcl58-cpp `_, @@ -118,9 +119,7 @@ `cert-err52-cpp `_, `cert-err58-cpp `_, `cert-err60-cpp `_, - `cert-exp42-c `_, `cert-flp30-c `_, - `cert-flp37-c `_, `cert-mem57-cpp `_, `cert-msc50-cpp `_, `cert-msc51-cpp `_, @@ -150,30 +149,30 @@ `concurrency-thread-canceltype-asynchronous `_, `cppcoreguidelines-avoid-goto `_, `cppcoreguidelines-avoid-non-const-global-variables `_, - `cppcoreguidelines-init-variables `_, "Yes" + `cppcoreguidelines-init-variables `_, `cppcoreguidelines-interfaces-global-init `_, `cppcoreguidelines-macro-usage `_, `cppcoreguidelines-narrowing-conversions `_, `cppcoreguidelines-no-malloc `_, `cppcoreguidelines-owning-memory `_, - `cppcoreguidelines-prefer-member-initializer `_, "Yes" + `cppcoreguidelines-prefer-member-initializer `_, `cppcoreguidelines-pro-bounds-array-to-pointer-decay `_, - `cppcoreguidelines-pro-bounds-constant-array-index `_, "Yes" + `cppcoreguidelines-pro-bounds-constant-array-index `_, `cppcoreguidelines-pro-bounds-pointer-arithmetic `_, `cppcoreguidelines-pro-type-const-cast `_, - `cppcoreguidelines-pro-type-cstyle-cast `_, "Yes" - `cppcoreguidelines-pro-type-member-init `_, "Yes" + `cppcoreguidelines-pro-type-cstyle-cast `_, + `cppcoreguidelines-pro-type-member-init `_, `cppcoreguidelines-pro-type-reinterpret-cast `_, - `cppcoreguidelines-pro-type-static-cast-downcast `_, "Yes" + `cppcoreguidelines-pro-type-static-cast-downcast `_, `cppcoreguidelines-pro-type-union-access `_, `cppcoreguidelines-pro-type-vararg `_, `cppcoreguidelines-slicing `_, `cppcoreguidelines-special-member-functions `_, - `cppcoreguidelines-virtual-class-destructor `_, "Yes" + `cppcoreguidelines-virtual-class-destructor `_, `darwin-avoid-spinlock `_, - `darwin-dispatch-once-nonstatic `_, "Yes" + `darwin-dispatch-once-nonstatic `_, `fuchsia-default-arguments-calls `_, - `fuchsia-default-arguments-declarations `_, "Yes" + `fuchsia-default-arguments-declarations `_, `fuchsia-multiple-inheritance `_, `fuchsia-overloaded-operator `_, `fuchsia-statically-constructed-objects `_, @@ -183,7 +182,7 @@ `google-build-namespaces `_, `google-build-using-namespace `_, `google-default-arguments `_, - `google-explicit-constructor `_, "Yes" + `google-explicit-constructor `_, `google-global-names-in-headers `_, `google-objc-avoid-nsobject-new `_, `google-objc-avoid-throwing-exception `_, @@ -194,7 +193,7 @@ `google-readability-todo `_, `google-runtime-int `_, `google-runtime-operator `_, - `google-upgrade-googletest-case `_, "Yes" + `google-upgrade-googletest-case `_, `hicpp-avoid-goto `_, `hicpp-exception-baseclass `_, `hicpp-multiway-paths-covered `_, @@ -202,125 +201,126 @@ `hicpp-signed-bitwise `_, `linuxkernel-must-use-errs `_, `llvm-header-guard `_, - `llvm-include-order `_, "Yes" + `llvm-include-order `_, `llvm-namespace-comment `_, - `llvm-prefer-isa-or-dyn-cast-in-conditionals `_, "Yes" - `llvm-prefer-register-over-unsigned `_, "Yes" - `llvm-twine-local `_, "Yes" + `llvm-prefer-isa-or-dyn-cast-in-conditionals `_, + `llvm-prefer-register-over-unsigned `_, + `llvm-twine-local `_, `llvmlibc-callee-namespace `_, `llvmlibc-implementation-in-namespace `_, - `llvmlibc-restrict-system-libc-headers `_, "Yes" - `misc-definitions-in-headers `_, "Yes" + `llvmlibc-restrict-system-libc-headers `_, + `misc-definitions-in-headers `_, `misc-misplaced-const `_, `misc-new-delete-overloads `_, `misc-no-recursion `_, `misc-non-copyable-objects `_, `misc-non-private-member-variables-in-classes `_, - `misc-redundant-expression `_, "Yes" - `misc-static-assert `_, "Yes" + `misc-redundant-expression `_, + `misc-static-assert `_, `misc-throw-by-value-catch-by-reference `_, `misc-unconventional-assign-operator `_, - `misc-uniqueptr-reset-release `_, "Yes" - `misc-unused-alias-decls `_, "Yes" - `misc-unused-parameters `_, "Yes" - `misc-unused-using-decls `_, "Yes" - `modernize-avoid-bind `_, "Yes" + `misc-uniqueptr-reset-release `_, + `misc-unused-alias-decls `_, + `misc-unused-parameters `_, + `misc-unused-using-decls `_, + `modernize-avoid-bind `_, `modernize-avoid-c-arrays `_, - `modernize-concat-nested-namespaces `_, "Yes" - `modernize-deprecated-headers `_, "Yes" - `modernize-deprecated-ios-base-aliases `_, "Yes" - `modernize-loop-convert `_, "Yes" - `modernize-make-shared `_, "Yes" - `modernize-make-unique `_, "Yes" - `modernize-pass-by-value `_, "Yes" - `modernize-raw-string-literal `_, "Yes" - `modernize-redundant-void-arg `_, "Yes" - `modernize-replace-auto-ptr `_, "Yes" - `modernize-replace-disallow-copy-and-assign-macro `_, "Yes" - `modernize-replace-random-shuffle `_, "Yes" - `modernize-return-braced-init-list `_, "Yes" - `modernize-shrink-to-fit `_, "Yes" - `modernize-unary-static-assert `_, "Yes" - `modernize-use-auto `_, "Yes" - `modernize-use-bool-literals `_, "Yes" - `modernize-use-default-member-init `_, "Yes" - `modernize-use-emplace `_, "Yes" - `modernize-use-equals-default `_, "Yes" - `modernize-use-equals-delete `_, "Yes" - `modernize-use-nodiscard `_, "Yes" - `modernize-use-noexcept `_, "Yes" - `modernize-use-nullptr `_, "Yes" - `modernize-use-override `_, "Yes" - `modernize-use-trailing-return-type `_, "Yes" - `modernize-use-transparent-functors `_, "Yes" - `modernize-use-uncaught-exceptions `_, "Yes" - `modernize-use-using `_, "Yes" - `mpi-buffer-deref `_, "Yes" - `mpi-type-mismatch `_, "Yes" + `modernize-concat-nested-namespaces `_, + `modernize-deprecated-headers `_, + `modernize-deprecated-ios-base-aliases `_, + `modernize-loop-convert `_, + `modernize-make-shared `_, + `modernize-make-unique `_, + `modernize-pass-by-value `_, + `modernize-raw-string-literal `_, + `modernize-redundant-void-arg `_, + `modernize-replace-auto-ptr `_, + `modernize-replace-disallow-copy-and-assign-macro `_, + `modernize-replace-random-shuffle `_, + `modernize-return-braced-init-list `_, + `modernize-shrink-to-fit `_, + `modernize-unary-static-assert `_, + `modernize-use-auto `_, + `modernize-use-bool-literals `_, + `modernize-use-default-member-init `_, + `modernize-use-emplace `_, + `modernize-use-equals-default `_, + `modernize-use-equals-delete `_, + `modernize-use-nodiscard `_, + `modernize-use-noexcept `_, + `modernize-use-nullptr `_, + `modernize-use-override `_, + `modernize-use-trailing-return-type `_, + `modernize-use-transparent-functors `_, + `modernize-use-uncaught-exceptions `_, + `modernize-use-using `_, + `mpi-buffer-deref `_, + `mpi-type-mismatch `_, `objc-avoid-nserror-init `_, `objc-dealloc-in-category `_, `objc-forbidden-subclassing `_, `objc-missing-hash `_, - `objc-nsinvocation-argument-lifetime `_, "Yes" - `objc-property-declaration `_, "Yes" - `objc-super-self `_, "Yes" + `objc-nsinvocation-argument-lifetime `_, + `objc-property-declaration `_, + `objc-super-self `_, `openmp-exception-escape `_, `openmp-use-default-none `_, - `performance-faster-string-find `_, "Yes" - `performance-for-range-copy `_, "Yes" + `performance-faster-string-find `_, + `performance-for-range-copy `_, `performance-implicit-conversion-in-loop `_, - `performance-inefficient-algorithm `_, "Yes" + `performance-inefficient-algorithm `_, `performance-inefficient-string-concatenation `_, - `performance-inefficient-vector-operation `_, "Yes" - `performance-move-const-arg `_, "Yes" + `performance-inefficient-vector-operation `_, + `performance-move-const-arg `_, `performance-move-constructor-init `_, `performance-no-automatic-move `_, `performance-no-int-to-ptr `_, - `performance-noexcept-move-constructor `_, "Yes" - `performance-trivially-destructible `_, "Yes" - `performance-type-promotion-in-math-fn `_, "Yes" + `performance-noexcept-move-constructor `_, + `performance-trivially-destructible `_, + `performance-type-promotion-in-math-fn `_, `performance-unnecessary-copy-initialization `_, - `performance-unnecessary-value-param `_, "Yes" - `portability-restrict-system-includes `_, "Yes" + `performance-unnecessary-value-param `_, + `portability-restrict-system-includes `_, `portability-simd-intrinsics `_, `readability-avoid-const-params-in-decls `_, - `readability-braces-around-statements `_, "Yes" - `readability-const-return-type `_, "Yes" - `readability-container-size-empty `_, "Yes" + `readability-braces-around-statements `_, + `readability-const-return-type `_, + `readability-container-size-empty `_, `readability-convert-member-functions-to-static `_, - `readability-delete-null-pointer `_, "Yes" - `readability-else-after-return `_, "Yes" + `readability-data-pointer `_, + `readability-delete-null-pointer `_, + `readability-else-after-return `_, `readability-function-cognitive-complexity `_, `readability-function-size `_, `readability-identifier-length `_, - `readability-identifier-naming `_, "Yes" - `readability-implicit-bool-conversion `_, "Yes" - `readability-inconsistent-declaration-parameter-name `_, "Yes" - `readability-isolate-declaration `_, "Yes" + `readability-identifier-naming `_, + `readability-implicit-bool-conversion `_, + `readability-inconsistent-declaration-parameter-name `_, + `readability-isolate-declaration `_, `readability-magic-numbers `_, - `readability-make-member-function-const `_, "Yes" + `readability-make-member-function-const `_, `readability-misleading-indentation `_, - `readability-misplaced-array-index `_, "Yes" - `readability-named-parameter `_, "Yes" - `readability-non-const-parameter `_, "Yes" - `readability-qualified-auto `_, "Yes" - `readability-redundant-access-specifiers `_, "Yes" - `readability-redundant-control-flow `_, "Yes" - `readability-redundant-declaration `_, "Yes" - `readability-redundant-function-ptr-dereference `_, "Yes" - `readability-redundant-member-init `_, "Yes" + `readability-misplaced-array-index `_, + `readability-named-parameter `_, + `readability-non-const-parameter `_, + `readability-qualified-auto `_, + `readability-redundant-access-specifiers `_, + `readability-redundant-control-flow `_, + `readability-redundant-declaration `_, + `readability-redundant-function-ptr-dereference `_, + `readability-redundant-member-init `_, `readability-redundant-preprocessor `_, - `readability-redundant-smartptr-get `_, "Yes" - `readability-redundant-string-cstr `_, "Yes" - `readability-redundant-string-init `_, "Yes" - `readability-simplify-boolean-expr `_, "Yes" - `readability-simplify-subscript-expr `_, "Yes" - `readability-static-accessed-through-instance `_, "Yes" - `readability-static-definition-in-anonymous-namespace `_, "Yes" - `readability-string-compare `_, "Yes" + `readability-redundant-smartptr-get `_, + `readability-redundant-string-cstr `_, + `readability-redundant-string-init `_, + `readability-simplify-boolean-expr `_, + `readability-simplify-subscript-expr `_, + `readability-static-accessed-through-instance `_, + `readability-static-definition-in-anonymous-namespace `_, + `readability-string-compare `_, `readability-suspicious-call-argument `_, - `readability-uniqueptr-delete-release `_, "Yes" - `readability-uppercase-literal-suffix `_, "Yes" + `readability-uniqueptr-delete-release `_, + `readability-uppercase-literal-suffix `_, `readability-use-anyofallof `_, `zircon-temporary-objects `_, @@ -330,15 +330,17 @@ `cert-con36-c `_, `bugprone-spuriously-wake-up-functions `_, `cert-con54-cpp `_, `bugprone-spuriously-wake-up-functions `_, - `cert-dcl03-c `_, `misc-static-assert `_, "Yes" - `cert-dcl16-c `_, `readability-uppercase-literal-suffix `_, "Yes" - `cert-dcl37-c `_, `bugprone-reserved-identifier `_, "Yes" - `cert-dcl51-cpp `_, `bugprone-reserved-identifier `_, "Yes" + `cert-dcl03-c `_, `misc-static-assert `_, + `cert-dcl16-c `_, `readability-uppercase-literal-suffix `_, + `cert-dcl37-c `_, `bugprone-reserved-identifier `_, + `cert-dcl51-cpp `_, `bugprone-reserved-identifier `_, `cert-dcl54-cpp `_, `misc-new-delete-overloads `_, `cert-dcl59-cpp `_, `google-build-namespaces `_, `cert-err09-cpp `_, `misc-throw-by-value-catch-by-reference `_, `cert-err61-cpp `_, `misc-throw-by-value-catch-by-reference `_, + `cert-exp42-c `_, `bugprone-suspicious-memory-comparison `_, `cert-fio38-c `_, `misc-non-copyable-objects `_, + `cert-flp37-c `_, `bugprone-suspicious-memory-comparison `_, `cert-msc30-c `_, `cert-msc50-cpp `_, `cert-msc32-c `_, `cert-msc51-cpp `_, `cert-oop11-cpp `_, `performance-move-constructor-init `_, @@ -414,36 +416,36 @@ `cppcoreguidelines-avoid-c-arrays `_, `modernize-avoid-c-arrays `_, `cppcoreguidelines-avoid-magic-numbers `_, `readability-magic-numbers `_, `cppcoreguidelines-c-copy-assignment-signature `_, `misc-unconventional-assign-operator `_, - `cppcoreguidelines-explicit-virtual-functions `_, `modernize-use-override `_, "Yes" + `cppcoreguidelines-explicit-virtual-functions `_, `modernize-use-override `_, `cppcoreguidelines-non-private-member-variables-in-classes `_, `misc-non-private-member-variables-in-classes `_, `fuchsia-header-anon-namespaces `_, `google-build-namespaces `_, - `google-readability-braces-around-statements `_, `readability-braces-around-statements `_, "Yes" + `google-readability-braces-around-statements `_, `readability-braces-around-statements `_, `google-readability-function-size `_, `readability-function-size `_, `google-readability-namespace-comments `_, `llvm-namespace-comment `_, `hicpp-avoid-c-arrays `_, `modernize-avoid-c-arrays `_, - `hicpp-braces-around-statements `_, `readability-braces-around-statements `_, "Yes" - `hicpp-deprecated-headers `_, `modernize-deprecated-headers `_, "Yes" - `hicpp-explicit-conversions `_, `google-explicit-constructor `_, "Yes" + `hicpp-braces-around-statements `_, `readability-braces-around-statements `_, + `hicpp-deprecated-headers `_, `modernize-deprecated-headers `_, + `hicpp-explicit-conversions `_, `google-explicit-constructor `_, `hicpp-function-size `_, `readability-function-size `_, `hicpp-invalid-access-moved `_, `bugprone-use-after-move `_, - `hicpp-member-init `_, `cppcoreguidelines-pro-type-member-init `_, "Yes" - `hicpp-move-const-arg `_, `performance-move-const-arg `_, "Yes" - `hicpp-named-parameter `_, `readability-named-parameter `_, "Yes" + `hicpp-member-init `_, `cppcoreguidelines-pro-type-member-init `_, + `hicpp-move-const-arg `_, `performance-move-const-arg `_, + `hicpp-named-parameter `_, `readability-named-parameter `_, `hicpp-new-delete-operators `_, `misc-new-delete-overloads `_, `hicpp-no-array-decay `_, `cppcoreguidelines-pro-bounds-array-to-pointer-decay `_, `hicpp-no-malloc `_, `cppcoreguidelines-no-malloc `_, - `hicpp-noexcept-move `_, `performance-noexcept-move-constructor `_, "Yes" + `hicpp-noexcept-move `_, `performance-noexcept-move-constructor `_, `hicpp-special-member-functions `_, `cppcoreguidelines-special-member-functions `_, - `hicpp-static-assert `_, `misc-static-assert `_, "Yes" + `hicpp-static-assert `_, `misc-static-assert `_, `hicpp-undelegated-constructor `_, `bugprone-undelegated-constructor `_, - `hicpp-uppercase-literal-suffix `_, `readability-uppercase-literal-suffix `_, "Yes" - `hicpp-use-auto `_, `modernize-use-auto `_, "Yes" - `hicpp-use-emplace `_, `modernize-use-emplace `_, "Yes" - `hicpp-use-equals-default `_, `modernize-use-equals-default `_, "Yes" - `hicpp-use-equals-delete `_, `modernize-use-equals-delete `_, "Yes" - `hicpp-use-noexcept `_, `modernize-use-noexcept `_, "Yes" - `hicpp-use-nullptr `_, `modernize-use-nullptr `_, "Yes" - `hicpp-use-override `_, `modernize-use-override `_, "Yes" + `hicpp-uppercase-literal-suffix `_, `readability-uppercase-literal-suffix `_, + `hicpp-use-auto `_, `modernize-use-auto `_, + `hicpp-use-emplace `_, `modernize-use-emplace `_, + `hicpp-use-equals-default `_, `modernize-use-equals-default `_, + `hicpp-use-equals-delete `_, `modernize-use-equals-delete `_, + `hicpp-use-noexcept `_, `modernize-use-noexcept `_, + `hicpp-use-nullptr `_, `modernize-use-nullptr `_, + `hicpp-use-override `_, `modernize-use-override `_, `hicpp-vararg `_, `cppcoreguidelines-pro-type-vararg `_, - `llvm-else-after-return `_, `readability-else-after-return `_, "Yes" - `llvm-qualified-auto `_, `readability-qualified-auto `_, "Yes" + `llvm-else-after-return `_, `readability-else-after-return `_, + `llvm-qualified-auto `_, `readability-qualified-auto `_, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-stringview-nullptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-stringview-nullptr.cpp new file mode 100644 --- /dev/null +++ b/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 +T &&declval(); + +template +struct type_identity { using type = T; }; +template +using type_identity_t = typename type_identity::type; + +template +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 +bool operator<(basic_string_view, basic_string_view); +template +bool operator<(type_identity_t>, basic_string_view); +template +bool operator<(basic_string_view, type_identity_t>); + +template +bool operator<=(basic_string_view, basic_string_view); +template +bool operator<=(type_identity_t>, basic_string_view); +template +bool operator<=(basic_string_view, type_identity_t>); + +template +bool operator>(basic_string_view, basic_string_view); +template +bool operator>(type_identity_t>, basic_string_view); +template +bool operator>(basic_string_view, type_identity_t>); + +template +bool operator>=(basic_string_view, basic_string_view); +template +bool operator>=(type_identity_t>, basic_string_view); +template +bool operator>=(basic_string_view, type_identity_t>); + +template +bool operator==(basic_string_view, basic_string_view); +template +bool operator==(type_identity_t>, basic_string_view); +template +bool operator==(basic_string_view, type_identity_t>); + +template +bool operator!=(basic_string_view, basic_string_view); +template +bool operator!=(type_identity_t>, basic_string_view); +template +bool operator!=(basic_string_view, type_identity_t>); + +using string_view = basic_string_view; + +} // 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(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{})) /* a29 */;{{$}} + + (void)(static_cast((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{})) /* a30 */;{{$}} + + // (void)(static_cast({nullptr})) /* a31 */; + // Braced initializer list does not compile in this context + + // (void)(static_cast({(nullptr)})) /* a32 */; + // Braced initializer list does not compile in this context + + (void)(static_cast(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(std::string_view{})) /* a33 */;{{$}} + + (void)(static_cast((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(std::string_view{})) /* a34 */;{{$}} + + // (void)(static_cast({nullptr})) /* a35 */; + // Braced initializer list does not compile in this context + + // (void)(static_cast({(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 + } +}