You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[clang] Fix pointer comparisons between pointers to constexpr-unknown (#147663)
A constexpr-unknown reference can be equal to an arbitrary value, except
values allocated during constant evaluation. Fix the handling.
The standard is unclear exactly which pointer comparisons count as
"unknown" in this context; for example, in some cases we could use
alignment to prove two constexpr-unknown references are not equal. I
decided to ignore all the cases involving variables not allocated during
constant evaluation.
While looking at this, I also spotted that there might be issues with
lifetimes, but I didn't try to address it.
(cherry picked from commit 20c8e3c)
// FIXME: interpreter incorrectly rejects; both sides are the same constexpr-unknown value.
331
331
static_assert(f1(false, extern_n)); // interpreter-error {{static assertion expression is not an integral constant expression}} \
332
332
// 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}} \
336
335
// interpreter-note {{initializer of 'extern_n' is unknown}}
337
336
voidf2(constint &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
-
constexprint x = &x == &n; // nointerpreter-error {{must be initialized by a constant expression}}
337
+
constexprint 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
+
constexprint y = &x == &y;
341
+
static_assert(!y);
342
342
}
343
+
constexprintf3() {
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
+
constexprintf4() {
351
+
int *p = newint;
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}} \
0 commit comments