https://github.com/offsetof created https://github.com/llvm/llvm-project/pull/89449
This patch disables the relevant diagnostic in C++17 and later modes. Fixes #45653 >From 44e3c7a4ced2ef1f8b78ab8b0009314fbcd05c6f Mon Sep 17 00:00:00 2001 From: offsetof <131769984+offse...@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:57:31 +0000 Subject: [PATCH] [clang] Allow constexpr relational comparison of unequal "void*" values Since C++17, it is no longer the case that applying relational operators to unequal pointers to "void" always produces an unspecified result. --- clang/lib/AST/ExprConstant.cpp | 5 ++++- clang/test/AST/Interp/literals.cpp | 10 +++++----- clang/test/CXX/drs/dr25xx.cpp | 1 + clang/test/CXX/drs/dr26xx.cpp | 2 ++ clang/test/CXX/drs/dr27xx.cpp | 22 ++++++++++++++++++++++ clang/test/CXX/expr/expr.const/p2-0x.cpp | 23 +++++++++++++---------- clang/www/cxx_dr_status.html | 6 +++--- 7 files changed, 50 insertions(+), 19 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 73ae8d8efb23a2..2d480edab833c8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13510,7 +13510,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, // operator is <= or >= and false otherwise; otherwise the result is // unspecified. // We interpret this as applying to pointers to *cv* void. - if (LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && IsRelational) + // This only applies until C++14; in C++17 a "cv void*" value can "point to + // an object" and is not treated specially in [expr.rel]. + if (!Info.getLangOpts().CPlusPlus17 && + LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && IsRelational) Info.CCEDiag(E, diag::note_constexpr_void_comparison); // C++11 [expr.rel]p2: diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 277438d2e63114..91857228fcddc7 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++11 -verify=expected,both %s // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++20 -verify=expected,both %s -// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-vla -verify=ref,both %s +// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-vla -verify=ref,ref-cxx11,both %s // RUN: %clang_cc1 -std=c++20 -fms-extensions -Wno-vla -verify=ref,both %s #define INT_MIN (~__INT_MAX__) @@ -193,10 +193,10 @@ namespace PointerComparison { /// FIXME: These two are rejected by the current interpreter, but /// accepted by GCC. - constexpr bool v5 = qv >= pv; // ref-error {{constant expression}} \ - // ref-note {{unequal pointers to void}} - constexpr bool v8 = qv > (void*)&s.a; // ref-error {{constant expression}} \ - // ref-note {{unequal pointers to void}} + constexpr bool v5 = qv >= pv; // ref-cxx11-error {{constant expression}} \ + // ref-cxx11-note {{unequal pointers to void}} + constexpr bool v8 = qv > (void*)&s.a; // ref-cxx11-error {{constant expression}} \ + // ref-cxx11-note {{unequal pointers to void}} constexpr bool v6 = qv > null; // both-error {{must be initialized by a constant expression}} \ // both-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} diff --git a/clang/test/CXX/drs/dr25xx.cpp b/clang/test/CXX/drs/dr25xx.cpp index 62b2a0a088cc13..672979c2be8ef8 100644 --- a/clang/test/CXX/drs/dr25xx.cpp +++ b/clang/test/CXX/drs/dr25xx.cpp @@ -83,6 +83,7 @@ using ::cwg2521::operator""_div; #endif } // namespace cwg2521 +// cwg2526: sup 2749 #if __cplusplus >= 202302L namespace cwg2553 { // cwg2553: 18 review 2023-07-14 diff --git a/clang/test/CXX/drs/dr26xx.cpp b/clang/test/CXX/drs/dr26xx.cpp index f7a05b9827a235..de18787bcab96b 100644 --- a/clang/test/CXX/drs/dr26xx.cpp +++ b/clang/test/CXX/drs/dr26xx.cpp @@ -238,3 +238,5 @@ void test() { } } #endif + +// cwg2696: dup 2749 diff --git a/clang/test/CXX/drs/dr27xx.cpp b/clang/test/CXX/drs/dr27xx.cpp index 0434427d6c92a3..1f5b9e571079c9 100644 --- a/clang/test/CXX/drs/dr27xx.cpp +++ b/clang/test/CXX/drs/dr27xx.cpp @@ -10,6 +10,28 @@ // expected-no-diagnostics #endif +namespace cwg2749 { // cwg2749: 19 +#if __cplusplus >= 201703L + +constexpr bool f() { + int arr[2] {}; + return (void*)arr < arr + 1; +} +static_assert(f()); + +constexpr bool g() { + struct { + char c; + short s; + int i; + } s {}; + return (void*)&s.c < &s.i; +} +static_assert(g()); + +#endif +} + namespace cwg2759 { // cwg2759: 19 #if __cplusplus >= 201103L diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index e3cd057baba75f..54e163f05e4524 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -571,18 +571,21 @@ namespace UnspecifiedRelations { // [expr.rel]p3: Pointers to void can be compared [...] if both pointers // represent the same address or are both the null pointer [...]; otherwise // the result is unspecified. - struct S { int a, b; } s; + struct S { int a, b; static int c; } s; constexpr void *null = 0; - constexpr void *pv = (void*)&s.a; - constexpr void *qv = (void*)&s.b; + constexpr void *av = (void*)&s.a; + constexpr void *bv = (void*)&s.b; + constexpr void *cv = (void*)&s.c; constexpr bool v1 = null < (int*)0; - constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}} - constexpr bool v3 = null == pv; // ok - constexpr bool v4 = qv == pv; // ok - constexpr bool v5 = qv >= pv; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} - constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} - constexpr bool v7 = qv <= (void*)&s.b; // ok - constexpr bool v8 = qv > (void*)&s.a; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} + constexpr bool v2 = null < av; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}} + constexpr bool v3 = null == av; // ok + constexpr bool v4 = bv == av; // ok + constexpr bool v5 = bv >= av; // cxx11-error {{constant expression}} cxx11-note {{unequal pointers to void}} + constexpr bool v6 = bv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} + constexpr bool v7 = bv <= (void*)&s.b; // ok + constexpr bool v8 = bv > (void*)&s.a; // cxx11-error {{constant expression}} cxx11-note {{unequal pointers to void}} + constexpr bool v9 = cv > bv; // expected-error {{constant expression}} expected-note {{comparison between '&c' and '&s.b' has unspecified value}} + constexpr bool v10 = cv <= (void*)&s; // expected-error {{constant expression}} expected-note {{comparison between '&c' and '&s' has unspecified value}} } // - an assignment or a compound assignment (5.17); or diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 83b71e7c122d1e..12075b5aa0451e 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -14964,7 +14964,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2526.html">2526</a></td> <td>C++23</td> <td>Relational comparison of <TT>void*</TT> pointers</td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Superseded by <a href="#2749">2749</a></td> </tr> <tr id="2527"> <td><a href="https://cplusplus.github.io/CWG/issues/2527.html">2527</a></td> @@ -15984,7 +15984,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2696.html">2696</a></td> <td>dup</td> <td>Relational comparisons of pointers to <TT>void</TT></td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Duplicate of <a href="#2749">2749</a></td> </tr> <tr id="2697"> <td><a href="https://cplusplus.github.io/CWG/issues/2697.html">2697</a></td> @@ -16302,7 +16302,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2749.html">2749</a></td> <td>DR</td> <td>Treatment of "pointer to void" for relational comparisons</td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Clang 19</td> </tr> <tr id="2750"> <td><a href="https://cplusplus.github.io/CWG/issues/2750.html">2750</a></td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits