[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG849b650cf3b6: [clang] Skip defaulted functions in zero-as-null-pointer-constant. (authored by massberg). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 Files: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++20 + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,12 @@ CodeSynthesisContext::RewritingOperatorAsSpaceship) return; + // Ignore null pointers in defaulted comparison operators. + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && FD->isDefaulted()) { +return; + } + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++20 + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === ---
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg added a comment. Note: The build failures are in parts of the code that isn't effected by this change. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg marked 2 inline comments as done. massberg added a comment. Thanks for the comments! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg updated this revision to Diff 478477. massberg added a comment. Fixed comments and removed unnecessary includes. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 Files: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++20 + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,12 @@ CodeSynthesisContext::RewritingOperatorAsSpaceship) return; + // Ignore null pointers in defaulted comparison operators. + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && FD->isDefaulted()) { +return; + } + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++20 + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,12 @@
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
ilya-biryukov accepted this revision. ilya-biryukov added a comment. This revision is now accepted and ready to land. LGTM with a few NITs. Thanks! Comment at: clang/lib/Sema/Sema.cpp:600 + // Ignore null pointers in defaulted functions, e.g. defaulted comparison + // operators. NIT: maybe even shorten to "ignore in defaulted comparison operators" Comment at: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp:3 + +#include + NIT: I believe you don't need it as you don't use definitions like `NULL` or `SYSTEM_MACRO` from this header. Similarly, `-isystem %S/Inputs` is not required. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg updated this revision to Diff 478261. massberg added a comment. Run clang-format on changed files. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 Files: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,13 @@ CodeSynthesisContext::RewritingOperatorAsSpaceship) return; + // Ignore null pointers in defaulted functions, e.g. defaulted comparison + // operators. + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && FD->isDefaulted()) { +return; + } + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg updated this revision to Diff 478227. massberg added a comment. Sync to head. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138727/new/ https://reviews.llvm.org/D138727 Files: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,13 @@ CodeSynthesisContext::RewritingOperatorAsSpaceship) return; + // Ignore null pointers in defaulted functions, e.g. defaulted comparison + // operators. + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && FD->isDefaulted()) { +return; + } + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6
[PATCH] D138727: [clang] Skip defaulted functions in zero-as-null-pointer-constant.
massberg created this revision. massberg added a reviewer: ilya-biryukov. Herald added a project: All. massberg requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. The zero-as-null-pointer-constant check should not fire if it is inside a defaulted function, e.g. defaulted spaceship operators. Add C++20 tests with spaceship operators. Fixes #50221 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D138727 Files: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2)); // expected-warning{{zero as null pointer constant}} +} Index: clang/lib/Sema/Sema.cpp === --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -597,6 +597,13 @@ CodeSynthesisContext::RewritingOperatorAsSpaceship) return; + // Ignore null pointers in defaulted functions, e.g. defaulted comparison + // operators. + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && FD->isDefaulted()) { +return; + } + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); Index: clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp === --- /dev/null +++ clang/test/SemaCXX/warn-zero-nullptr-cxx20.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++20 + +#include + +namespace std { +class strong_ordering; + +// Mock how STD defined unspecified parameters for the operators below. +struct _CmpUnspecifiedParam { + consteval + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} +}; + +struct strong_ordering { + 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}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +struct A { + int a; + constexpr auto operator<=>(const A ) const = default; +}; + +void test_cxx_rewritten_binary_ops() { + A a1, a2; + bool result; + result = (a1 < a2); + result = (a1 >= a2); + int *ptr = 0; // expected-warning{{zero as null pointer constant}} + result = (a1 > (ptr == 0 ? a1 : a2)); // expected-warning{{zero as null pointer constant}} + result = (a1 > ((a1 > (ptr == 0 ?