Author: Richard Smith Date: 2021-02-03T14:58:53-08:00 New Revision: 1f06f41993b6363e6b2c4f22a13488a3e687f31b
URL: https://github.com/llvm/llvm-project/commit/1f06f41993b6363e6b2c4f22a13488a3e687f31b DIFF: https://github.com/llvm/llvm-project/commit/1f06f41993b6363e6b2c4f22a13488a3e687f31b.diff LOG: PR44325 (and duplicates): don't issue -Wzero-as-null-pointer-constant when rewriting 'a < b' as '(a <=> b) < 0'. It's pretty common for comparison category types to use a pointer or pointer-to-member type as their '0' parameter. Added: Modified: clang/lib/Sema/Sema.cpp clang/test/SemaCXX/cxx2a-three-way-comparison.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 55cb3aee6194..cb5a84a31235 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -537,6 +537,13 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) { if (E->IgnoreParenImpCasts()->getType()->isNullPtrType()) return; + // Don't diagnose the conversion from a 0 literal to a null pointer argument + // in a synthesized call to operator<=>. + if (!CodeSynthesisContexts.empty() && + CodeSynthesisContexts.back().Kind == + CodeSynthesisContext::RewritingOperatorAsSpaceship) + return; + // If it is a macro from system header, and if the macro name is not "NULL", // do not warn. SourceLocation MaybeMacroLoc = E->getBeginLoc(); diff --git a/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp index 353360e052bb..b94225274fff 100644 --- a/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp +++ b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++2a -verify %s +// RUN: %clang_cc1 -std=c++2a -verify %s -Wzero-as-null-pointer-constant // Keep this test before any declarations of operator<=>. namespace PR44786 { @@ -40,3 +40,21 @@ namespace PR47893 { int &f(...); int &r = f(A(), A()); } + +namespace PR44325 { + struct cmp_cat {}; + bool operator<(cmp_cat, void*); + bool operator>(cmp_cat, int cmp_cat::*); + + struct X {}; + cmp_cat operator<=>(X, X); + + bool b1 = X() < X(); // no warning + bool b2 = X() > X(); // no warning + + // FIXME: It's not clear whether warning here is useful, but we can't really + // tell that this is a comparison category in general. This is probably OK, + // as comparisons against zero are only really intended for use in the + // implicit rewrite rules, not for explicit use by programs. + bool c = cmp_cat() < 0; // expected-warning {{zero as null pointer constant}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits