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

            Bug ID: 118923
           Summary: Wrong code generated for member function pointer call
                    in range-for loop
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kacper.slominski72 at gmail dot com
  Target Milestone: ---

The following code, when compiled with `-O3 -std=c++23` for x86_64, produces
wrong assembly that unconditionally causes a call to NULL.

#include <vector>

struct Workspace {
        std::vector<int> previousRestrictedMoveArea();
        std::vector<int> restrictedMoveArea();
        bool inRearrange() {
                return m_inRearrange;
        }

        bool m_inRearrange = false;

        static Workspace _self;
};

inline Workspace *workspace() {
        return &Workspace::_self;
}

void foo() {
        auto moveAreaFunc = workspace()->inRearrange() ?
&Workspace::previousRestrictedMoveArea :
                &Workspace::restrictedMoveArea;

        for (const int &r : (workspace()->*moveAreaFunc)()) {
        }
}


Bad fragment of the generated assembly:
        leaq    _ZN9Workspace5_selfE(%rip), %rsi
        xorl    %eax, %eax
        movq    %rsp, %rdi
        call    *%rax


Originally found in KWin, then reduced from there.

Reply via email to