poelmanc updated this revision to Diff 320330.
poelmanc added a comment.

Thanks to the great feedback, changed 
`unless(hasAncestor(cxxRewrittenBinaryOperator()))` to 
`unless(hasParent(expr(hasParent(cxxRewrittenBinaryOperator()))))` and added a 
test to verify the improvement (and removed an extraneous comment.)


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

https://reviews.llvm.org/D95714

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
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-cxx20.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t
+
+namespace std {
+
+struct strong_ordering {
+  static const strong_ordering less;
+  static const strong_ordering equal;
+  static const strong_ordering greater;
+  using zero_type = decltype(nullptr);
+
+  friend constexpr bool operator<(const strong_ordering value, zero_type) 
noexcept {
+    return value.comparison_value < 0;
+  }
+
+  friend constexpr bool operator>(const strong_ordering value, zero_type) 
noexcept {
+    return value.comparison_value > 0;
+  }
+
+  friend constexpr bool operator>=(const strong_ordering value, zero_type) 
noexcept {
+    return value.comparison_value >= 0;
+  }
+
+  signed char comparison_value;
+};
+
+inline constexpr strong_ordering strong_ordering::less{-1};
+inline constexpr strong_ordering strong_ordering::equal{0};
+inline constexpr strong_ordering strong_ordering::greater{1};
+
+} // namespace std
+
+class A {
+public:
+  auto operator<=>(const A &other) const = default;
+};
+
+void test_cxx_rewritten_binary_ops() {
+  A a1, a2;
+  bool result;
+  // should not change next line to (a1 nullptr a2)
+  result = (a1 < a2);
+  // CHECK-FIXES: result = (a1 < a2);
+  // should not change next line to (a1 nullptr a2)
+  result = (a1 >= a2);
+  // CHECK-FIXES: result = (a1 >= a2);
+  int *ptr = 0;
+  // CHECK-FIXES: int *ptr = nullptr;
+  result = (a1 > (ptr == 0 ? a1 : a2));
+  // CHECK-FIXES: result = (a1 > (ptr == nullptr ? a1 : a2));
+}
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
@@ -45,6 +45,8 @@
       TK_AsIs,
       castExpr(anyOf(ImplicitCastToNull,
                      explicitCastExpr(hasDescendant(ImplicitCastToNull))),
+               // Skip implicit casts to 0 generated by operator<=> rewrites.
+               
unless(hasParent(expr(hasParent(cxxRewrittenBinaryOperator())))),
                unless(hasAncestor(explicitCastExpr())))
           .bind(CastSequence));
 }


Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-cxx20.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-cxx20.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t
+
+namespace std {
+
+struct strong_ordering {
+  static const strong_ordering less;
+  static const strong_ordering equal;
+  static const strong_ordering greater;
+  using zero_type = decltype(nullptr);
+
+  friend constexpr bool operator<(const strong_ordering value, zero_type) noexcept {
+    return value.comparison_value < 0;
+  }
+
+  friend constexpr bool operator>(const strong_ordering value, zero_type) noexcept {
+    return value.comparison_value > 0;
+  }
+
+  friend constexpr bool operator>=(const strong_ordering value, zero_type) noexcept {
+    return value.comparison_value >= 0;
+  }
+
+  signed char comparison_value;
+};
+
+inline constexpr strong_ordering strong_ordering::less{-1};
+inline constexpr strong_ordering strong_ordering::equal{0};
+inline constexpr strong_ordering strong_ordering::greater{1};
+
+} // namespace std
+
+class A {
+public:
+  auto operator<=>(const A &other) const = default;
+};
+
+void test_cxx_rewritten_binary_ops() {
+  A a1, a2;
+  bool result;
+  // should not change next line to (a1 nullptr a2)
+  result = (a1 < a2);
+  // CHECK-FIXES: result = (a1 < a2);
+  // should not change next line to (a1 nullptr a2)
+  result = (a1 >= a2);
+  // CHECK-FIXES: result = (a1 >= a2);
+  int *ptr = 0;
+  // CHECK-FIXES: int *ptr = nullptr;
+  result = (a1 > (ptr == 0 ? a1 : a2));
+  // CHECK-FIXES: result = (a1 > (ptr == nullptr ? a1 : a2));
+}
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
@@ -45,6 +45,8 @@
       TK_AsIs,
       castExpr(anyOf(ImplicitCastToNull,
                      explicitCastExpr(hasDescendant(ImplicitCastToNull))),
+               // Skip implicit casts to 0 generated by operator<=> rewrites.
+               unless(hasParent(expr(hasParent(cxxRewrittenBinaryOperator())))),
                unless(hasAncestor(explicitCastExpr())))
           .bind(CastSequence));
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to