Skip to content

Commit 5e976da

Browse files
author
git apple-llvm automerger
committed
Merge commit '2067574f54dd' from llvm.org/release/21.x into stable/21.x
2 parents 11e7741 + 2067574 commit 5e976da

File tree

4 files changed

+44
-14
lines changed

4 files changed

+44
-14
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ Bug Fixes to C++ Support
967967
- Fix a crash with NTTP when instantiating local class.
968968
- Fixed a crash involving list-initialization of an empty class with a
969969
non-empty initializer list. (#GH147949)
970+
- Fixed constant evaluation of equality comparisons of constexpr-unknown references. (#GH147663)
970971

971972
Bug Fixes to AST Handling
972973
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14918,12 +14918,6 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1491814918
if (!EvaluatePointer(E->getRHS(), RHSValue, Info) || !LHSOK)
1491914919
return false;
1492014920

14921-
// If we have Unknown pointers we should fail if they are not global values.
14922-
if (!(IsGlobalLValue(LHSValue.getLValueBase()) &&
14923-
IsGlobalLValue(RHSValue.getLValueBase())) &&
14924-
(LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
14925-
return false;
14926-
1492714921
// Reject differing bases from the normal codepath; we special-case
1492814922
// comparisons to null.
1492914923
if (!HasSameBase(LHSValue, RHSValue)) {
@@ -14985,6 +14979,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1498514979
(LHSValue.Base && isZeroSized(RHSValue)))
1498614980
return DiagComparison(
1498714981
diag::note_constexpr_pointer_comparison_zero_sized);
14982+
if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
14983+
return DiagComparison(
14984+
diag::note_constexpr_pointer_comparison_unspecified);
14985+
// FIXME: Verify both variables are live.
1498814986
return Success(CmpResult::Unequal, E);
1498914987
}
1499014988

clang/test/SemaCXX/constant-expression-cxx14.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,3 +1321,18 @@ constexpr bool check = different_in_loop();
13211321
// expected-error@-1 {{}} expected-note@-1 {{in call}}
13221322

13231323
}
1324+
1325+
namespace comparison_dead_variable {
1326+
constexpr bool f() {
1327+
int *p1 = 0, *p2 = 0;
1328+
{
1329+
int x = 0; p1 = &x;
1330+
}
1331+
{
1332+
int x = 0; p2 = &x;
1333+
}
1334+
return p1 != p2;
1335+
}
1336+
// FIXME: This should fail.
1337+
static_assert(f(),"");
1338+
}

clang/test/SemaCXX/constant-expression-p2280r4.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ namespace casting {
319319
}
320320

321321
namespace pointer_comparisons {
322-
extern int &extern_n; // interpreter-note 2 {{declared here}}
322+
extern int &extern_n; // interpreter-note 4 {{declared here}}
323323
extern int &extern_n2;
324324
constexpr int f1(bool b, int& n) {
325325
if (b) {
@@ -330,14 +330,30 @@ namespace pointer_comparisons {
330330
// FIXME: interpreter incorrectly rejects; both sides are the same constexpr-unknown value.
331331
static_assert(f1(false, extern_n)); // interpreter-error {{static assertion expression is not an integral constant expression}} \
332332
// interpreter-note {{initializer of 'extern_n' is unknown}}
333-
// FIXME: We should diagnose this: we don't know if the references bind
334-
// to the same object.
335-
static_assert(&extern_n != &extern_n2); // interpreter-error {{static assertion expression is not an integral constant expression}} \
333+
static_assert(&extern_n != &extern_n2); // expected-error {{static assertion expression is not an integral constant expression}} \
334+
// nointerpreter-note {{comparison between pointers to unrelated objects '&extern_n' and '&extern_n2' has unspecified value}} \
336335
// interpreter-note {{initializer of 'extern_n' is unknown}}
337336
void f2(const int &n) {
338-
// FIXME: We should not diagnose this: the two objects provably have
339-
// different addresses because the lifetime of "n" extends across
340-
// the initialization.
341-
constexpr int x = &x == &n; // nointerpreter-error {{must be initialized by a constant expression}}
337+
constexpr int x = &x == &n; // nointerpreter-error {{must be initialized by a constant expression}} \
338+
// nointerpreter-note {{comparison between pointers to unrelated objects '&x' and '&n' has unspecified value}}
339+
// Distinct variables are not equal, even if they're local variables.
340+
constexpr int y = &x == &y;
341+
static_assert(!y);
342342
}
343+
constexpr int f3() {
344+
int x;
345+
return &x == &extern_n; // nointerpreter-note {{comparison between pointers to unrelated objects '&x' and '&extern_n' has unspecified value}} \
346+
// interpreter-note {{initializer of 'extern_n' is unknown}}
347+
}
348+
static_assert(!f3()); // expected-error {{static assertion expression is not an integral constant expression}} \
349+
// expected-note {{in call to 'f3()'}}
350+
constexpr int f4() {
351+
int *p = new int;
352+
bool b = p == &extern_n; // nointerpreter-note {{comparison between pointers to unrelated objects '&{*new int#0}' and '&extern_n' has unspecified value}} \
353+
// interpreter-note {{initializer of 'extern_n' is unknown}}
354+
delete p;
355+
return b;
356+
}
357+
static_assert(!f4()); // expected-error {{static assertion expression is not an integral constant expression}} \
358+
// expected-note {{in call to 'f4()'}}
343359
}

0 commit comments

Comments
 (0)