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

            Bug ID: 122084
           Summary: Self-referential objects work poorly in constexpr
                    dtors
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: blubban at gmail dot com
  Target Milestone: ---

struct iterator {
    iterator* next;
    //iterator* keepalive = this;

    constexpr explicit iterator() {
        next = this;
    }
    constexpr explicit iterator(iterator* prev) {
        next = prev->next;
        prev->next = this;
    }

    constexpr iterator(const iterator&) = delete;
    iterator& operator=(const iterator&) = delete;

    constexpr ~iterator() {
        iterator* it = next;
        while (true)
        {
            if (it->next == this) {
                it->next = next;
                break;
            }
            it = it->next;
        }
    }
};

constexpr iterator copy(iterator* first) {
    return iterator(first);
}

constexpr bool test() {
    iterator root;
    iterator it { copy(&root) };
    return true;
}

static_assert(test());


-std=c++20


Expected: Compile successfully, as under Clang and MSVC.
https://godbolt.org/z/7bKxbdqb9

Actual:

<source>:39:19: error: non-constant condition for static assertion
   39 | static_assert(test());
      |               ~~~~^~
<source>:39:19:   in 'constexpr' expansion of 'test()'
<source>:37:1:   in 'constexpr' expansion of '(& it)->iterator::~iterator()'
<source>:20:21: error: ''result_decl' not supported by dump_expr<expression
error>' is not a constant expression
   20 |             if (it->next == this) {
      |                 ~~~~^~~~


Oddly enough, it compiles successfully if I uncomment the keepalive member.

Reply via email to