Skip to content

Commit 44e3c7a

Browse files
committed
[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.
1 parent cee7d99 commit 44e3c7a

File tree

7 files changed

+50
-19
lines changed

7 files changed

+50
-19
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13510,7 +13510,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1351013510
// operator is <= or >= and false otherwise; otherwise the result is
1351113511
// unspecified.
1351213512
// We interpret this as applying to pointers to *cv* void.
13513-
if (LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && IsRelational)
13513+
// This only applies until C++14; in C++17 a "cv void*" value can "point to
13514+
// an object" and is not treated specially in [expr.rel].
13515+
if (!Info.getLangOpts().CPlusPlus17 &&
13516+
LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && IsRelational)
1351413517
Info.CCEDiag(E, diag::note_constexpr_void_comparison);
1351513518

1351613519
// C++11 [expr.rel]p2:

clang/test/AST/Interp/literals.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++11 -verify=expected,both %s
22
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++20 -verify=expected,both %s
3-
// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-vla -verify=ref,both %s
3+
// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-vla -verify=ref,ref-cxx11,both %s
44
// RUN: %clang_cc1 -std=c++20 -fms-extensions -Wno-vla -verify=ref,both %s
55

66
#define INT_MIN (~__INT_MAX__)
@@ -193,10 +193,10 @@ namespace PointerComparison {
193193

194194
/// FIXME: These two are rejected by the current interpreter, but
195195
/// accepted by GCC.
196-
constexpr bool v5 = qv >= pv; // ref-error {{constant expression}} \
197-
// ref-note {{unequal pointers to void}}
198-
constexpr bool v8 = qv > (void*)&s.a; // ref-error {{constant expression}} \
199-
// ref-note {{unequal pointers to void}}
196+
constexpr bool v5 = qv >= pv; // ref-cxx11-error {{constant expression}} \
197+
// ref-cxx11-note {{unequal pointers to void}}
198+
constexpr bool v8 = qv > (void*)&s.a; // ref-cxx11-error {{constant expression}} \
199+
// ref-cxx11-note {{unequal pointers to void}}
200200
constexpr bool v6 = qv > null; // both-error {{must be initialized by a constant expression}} \
201201
// both-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
202202

clang/test/CXX/drs/dr25xx.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ using ::cwg2521::operator""_div;
8383
#endif
8484
} // namespace cwg2521
8585

86+
// cwg2526: sup 2749
8687

8788
#if __cplusplus >= 202302L
8889
namespace cwg2553 { // cwg2553: 18 review 2023-07-14

clang/test/CXX/drs/dr26xx.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,5 @@ void test() {
238238
}
239239
}
240240
#endif
241+
242+
// cwg2696: dup 2749

clang/test/CXX/drs/dr27xx.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@
1010
// expected-no-diagnostics
1111
#endif
1212

13+
namespace cwg2749 { // cwg2749: 19
14+
#if __cplusplus >= 201703L
15+
16+
constexpr bool f() {
17+
int arr[2] {};
18+
return (void*)arr < arr + 1;
19+
}
20+
static_assert(f());
21+
22+
constexpr bool g() {
23+
struct {
24+
char c;
25+
short s;
26+
int i;
27+
} s {};
28+
return (void*)&s.c < &s.i;
29+
}
30+
static_assert(g());
31+
32+
#endif
33+
}
34+
1335
namespace cwg2759 { // cwg2759: 19
1436
#if __cplusplus >= 201103L
1537

clang/test/CXX/expr/expr.const/p2-0x.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -571,18 +571,21 @@ namespace UnspecifiedRelations {
571571
// [expr.rel]p3: Pointers to void can be compared [...] if both pointers
572572
// represent the same address or are both the null pointer [...]; otherwise
573573
// the result is unspecified.
574-
struct S { int a, b; } s;
574+
struct S { int a, b; static int c; } s;
575575
constexpr void *null = 0;
576-
constexpr void *pv = (void*)&s.a;
577-
constexpr void *qv = (void*)&s.b;
576+
constexpr void *av = (void*)&s.a;
577+
constexpr void *bv = (void*)&s.b;
578+
constexpr void *cv = (void*)&s.c;
578579
constexpr bool v1 = null < (int*)0;
579-
constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}}
580-
constexpr bool v3 = null == pv; // ok
581-
constexpr bool v4 = qv == pv; // ok
582-
constexpr bool v5 = qv >= pv; // expected-error {{constant expression}} expected-note {{unequal pointers to void}}
583-
constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
584-
constexpr bool v7 = qv <= (void*)&s.b; // ok
585-
constexpr bool v8 = qv > (void*)&s.a; // expected-error {{constant expression}} expected-note {{unequal pointers to void}}
580+
constexpr bool v2 = null < av; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}}
581+
constexpr bool v3 = null == av; // ok
582+
constexpr bool v4 = bv == av; // ok
583+
constexpr bool v5 = bv >= av; // cxx11-error {{constant expression}} cxx11-note {{unequal pointers to void}}
584+
constexpr bool v6 = bv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
585+
constexpr bool v7 = bv <= (void*)&s.b; // ok
586+
constexpr bool v8 = bv > (void*)&s.a; // cxx11-error {{constant expression}} cxx11-note {{unequal pointers to void}}
587+
constexpr bool v9 = cv > bv; // expected-error {{constant expression}} expected-note {{comparison between '&c' and '&s.b' has unspecified value}}
588+
constexpr bool v10 = cv <= (void*)&s; // expected-error {{constant expression}} expected-note {{comparison between '&c' and '&s' has unspecified value}}
586589
}
587590

588591
// - an assignment or a compound assignment (5.17); or

clang/www/cxx_dr_status.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14964,7 +14964,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1496414964
<td><a href="https://cplusplus.github.io/CWG/issues/2526.html">2526</a></td>
1496514965
<td>C++23</td>
1496614966
<td>Relational comparison of <TT>void*</TT> pointers</td>
14967-
<td class="unknown" align="center">Unknown</td>
14967+
<td class="unreleased" align="center">Superseded by <a href="#2749">2749</a></td>
1496814968
</tr>
1496914969
<tr id="2527">
1497014970
<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>
1598415984
<td><a href="https://cplusplus.github.io/CWG/issues/2696.html">2696</a></td>
1598515985
<td>dup</td>
1598615986
<td>Relational comparisons of pointers to <TT>void</TT></td>
15987-
<td class="unknown" align="center">Unknown</td>
15987+
<td class="unreleased" align="center">Duplicate of <a href="#2749">2749</a></td>
1598815988
</tr>
1598915989
<tr id="2697">
1599015990
<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>
1630216302
<td><a href="https://cplusplus.github.io/CWG/issues/2749.html">2749</a></td>
1630316303
<td>DR</td>
1630416304
<td>Treatment of "pointer to void" for relational comparisons</td>
16305-
<td class="unknown" align="center">Unknown</td>
16305+
<td class="unreleased" align="center">Clang 19</td>
1630616306
</tr>
1630716307
<tr id="2750">
1630816308
<td><a href="https://cplusplus.github.io/CWG/issues/2750.html">2750</a></td>

0 commit comments

Comments
 (0)