https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118461

            Bug ID: 118461
           Summary: constexpr lifetime tracking allows access to
                    out-of-lifetime const variables
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: richard-gccbugzilla at metafoo dot co.uk
  Target Milestone: ---

Even after the fix for PR96630, GCC still accepts this invalid code that
accesses a variable outside its lifetime:

constexpr int f() {
  const int *p = 0;
  for (int i = 0; i != 2; ++i) {
    if (i == 1) { return *p; }
    const int n = 0;
    p = &n;
  }
}
static_assert(f() == 0);

(Live: https://godbolt.org/z/3fEEoq3T6)

Even though `*p` denotes `n`, which is usable in constant expressions, the
evaluation of `*p` still has undefined behavior because `n` is not within its
lifetime, so this is non-constant by [expr.const]/10.8.

Note in particular that the special provision in [expr.const]/17 that
effectively says we get to ignore the lifetime rules in some cases does not
apply to variables whose lifetime started within the evaluation. So this is
valid:

void g() {
  const int n = 0;
  static_assert([] { return n; }() == 0);
}

... because we get to assume that n is alive throughout the evaluation, but the
same doesn't apply in the testcase above, because the lifetime of the variable
started within the evaluation of `f() == 0`.

Reply via email to