Skip to content

Commit db335d0

Browse files
jensmassbergilya-biryukov
authored andcommitted
[clang-tidy] Ignore cxxRewrittenBinaryOperator in defaulted function decls in modernize-use-nullptr
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 llvm#53961. Patch by Jens Massberg. Reviewed By: ilya-biryukov Differential Revision: https://reviews.llvm.org/D138701
1 parent d65019b commit db335d0

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ StatementMatcher makeCastSequenceMatcher() {
6262
ImplicitCastToNull,
6363
hasAncestor(cxxRewrittenBinaryOperator().bind(
6464
"checkBinopOperands")))
65-
.bind(CastSequence))))));
65+
.bind(CastSequence))),
66+
// Skip defaulted comparison operators.
67+
unless(hasAncestor(functionDecl(isDefaulted()))))));
6668
}
6769

6870
bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,

clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
// RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t
22

33
namespace std {
4+
class strong_ordering;
5+
6+
// Mock how STD defined unspecified parameters for the operators below.
7+
struct _CmpUnspecifiedParam {
8+
consteval
9+
_CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
10+
};
11+
412
struct strong_ordering {
5-
int n;
6-
constexpr operator int() const { return n; }
13+
signed char value;
14+
15+
friend constexpr bool operator==(strong_ordering v,
16+
_CmpUnspecifiedParam) noexcept {
17+
return v.value == 0;
18+
}
19+
friend constexpr bool operator<(strong_ordering v,
20+
_CmpUnspecifiedParam) noexcept {
21+
return v.value < 0;
22+
}
23+
friend constexpr bool operator>(strong_ordering v,
24+
_CmpUnspecifiedParam) noexcept {
25+
return v.value > 0;
26+
}
27+
friend constexpr bool operator>=(strong_ordering v,
28+
_CmpUnspecifiedParam) noexcept {
29+
return v.value >= 0;
30+
}
731
static const strong_ordering equal, greater, less;
832
};
933
constexpr strong_ordering strong_ordering::equal = {0};
@@ -12,8 +36,10 @@ constexpr strong_ordering strong_ordering::less = {-1};
1236
} // namespace std
1337

1438
class A {
39+
int a;
1540
public:
1641
auto operator<=>(const A &other) const = default;
42+
// CHECK-FIXES: auto operator<=>(const A &other) const = default;
1743
};
1844

1945
void test_cxx_rewritten_binary_ops() {
@@ -32,3 +58,14 @@ void test_cxx_rewritten_binary_ops() {
3258
result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2));
3359
// CHECK-FIXES: result = (a1 > ((a1 > (ptr == nullptr ? a1 : a2)) ? a1 : a2));
3460
}
61+
62+
template<class T1, class T2>
63+
struct P {
64+
T1 x1;
65+
T2 x2;
66+
friend auto operator<=>(const P&, const P&) = default;
67+
// CHECK-FIXES: friend auto operator<=>(const P&, const P&) = default;
68+
};
69+
70+
bool foo(P<int,int> x, P<int, int> y) { return x < y; }
71+
// CHECK-FIXES: bool foo(P<int,int> x, P<int, int> y) { return x < y; }

0 commit comments

Comments
 (0)