massberg created this revision. massberg added a reviewer: ilya-biryukov. Herald added subscribers: carlosgalvezp, xazax.hun. Herald added a reviewer: njames93. Herald added a project: All. massberg requested review of this revision. Herald added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
The check has produced false positives when checking the default implementation of the spaceship operator. The default implementation should be skipped by the check. Modified the existing test so that the check runs into the bug without this fix and add another test case. Fixes #53961 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D138701 Files: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp @@ -1,9 +1,32 @@ // RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t namespace std { +class strong_ordering; + +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + struct strong_ordering { - int n; - constexpr operator int() const { return n; } + signed char value; + + friend constexpr bool operator==(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value == 0; + } + friend constexpr bool operator<(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value < 0; + } + friend constexpr bool operator>(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value > 0; + } + friend constexpr bool operator>=(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value >= 0; + } static const strong_ordering equal, greater, less; }; constexpr strong_ordering strong_ordering::equal = {0}; @@ -12,8 +35,10 @@ } // namespace std class A { + int a; public: auto operator<=>(const A &other) const = default; + // CHECK-FIXES: auto operator<=>(const A &other) const = default; }; void test_cxx_rewritten_binary_ops() { @@ -32,3 +57,14 @@ result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // CHECK-FIXES: result = (a1 > ((a1 > (ptr == nullptr ? a1 : a2)) ? a1 : a2)); } + +template<class T1, class T2> +struct P { + T1 x1; + T2 x2; + friend auto operator<=>(const P&, const P&) = default; + // CHECK-FIXES: friend auto operator<=>(const P&, const P&) = default; +}; + +bool foo(P<int,int> x, P<int, int> y) { return x < y; } +// CHECK-FIXES: bool foo(P<int,int> x, P<int, int> y) { return x < y; } Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -62,7 +62,8 @@ ImplicitCastToNull, hasAncestor(cxxRewrittenBinaryOperator().bind( "checkBinopOperands"))) - .bind(CastSequence)))))); + .bind(CastSequence))), + unless(hasAncestor(functionDecl(isDefaulted())))))); } bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp @@ -1,9 +1,32 @@ // RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t namespace std { +class strong_ordering; + +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + struct strong_ordering { - int n; - constexpr operator int() const { return n; } + signed char value; + + friend constexpr bool operator==(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value == 0; + } + friend constexpr bool operator<(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value < 0; + } + friend constexpr bool operator>(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value > 0; + } + friend constexpr bool operator>=(strong_ordering v, + _CmpUnspecifiedParam) noexcept { + return v.value >= 0; + } static const strong_ordering equal, greater, less; }; constexpr strong_ordering strong_ordering::equal = {0}; @@ -12,8 +35,10 @@ } // namespace std class A { + int a; public: auto operator<=>(const A &other) const = default; + // CHECK-FIXES: auto operator<=>(const A &other) const = default; }; void test_cxx_rewritten_binary_ops() { @@ -32,3 +57,14 @@ result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // CHECK-FIXES: result = (a1 > ((a1 > (ptr == nullptr ? a1 : a2)) ? a1 : a2)); } + +template<class T1, class T2> +struct P { + T1 x1; + T2 x2; + friend auto operator<=>(const P&, const P&) = default; + // CHECK-FIXES: friend auto operator<=>(const P&, const P&) = default; +}; + +bool foo(P<int,int> x, P<int, int> y) { return x < y; } +// CHECK-FIXES: bool foo(P<int,int> x, P<int, int> y) { return x < y; } Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -62,7 +62,8 @@ ImplicitCastToNull, hasAncestor(cxxRewrittenBinaryOperator().bind( "checkBinopOperands"))) - .bind(CastSequence)))))); + .bind(CastSequence))), + unless(hasAncestor(functionDecl(isDefaulted())))))); } bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits