mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 19:51:23 +08:00
This wrong-code PR for the C++ compiler on x86-64/Windows is a regression in GCC 9 and later, but the underlying issue has probably been there since SEH was implemented and is exposed by this comment in config/i386/winnt.c: /* SEH records saves relative to the "current" stack pointer, whether or not there's a frame pointer in place. This tracks the current stack pointer offset from the CFA. */ HOST_WIDE_INT sp_offset; That's not what the (current) Microsoft documentation says; instead it says: /* SEH records offsets relative to the lowest address of the fixed stack allocation. If there is no frame pointer, these offsets are from the stack pointer; if there is a frame pointer, these offsets are from the value of the stack pointer when the frame pointer was established, i.e. the frame pointer minus the offset in the .seh_setframe directive. */ That's why the implementation is correct only under the condition that the frame pointer be established *after* the fixed stack allocation; as a matter of fact, that's clearly the model underpinning SEH, but is the opposite of what is done e.g. on Linux. However the issue is mostly papered over in practice because: 1. SEH forces use_fast_prologue_epilogue to false, which in turns forces save_regs_using_mov to false, so the general regs are always pushed when they need to be saved, which eliminates the offset computation for them. 2. As soon as a frame is larger than 240 bytes, the frame pointer is fixed arbitrarily to 128 bytes above the stack pointer, which of course requires that it be established after the fixed stack allocation. So you need a small frame clobbering one of the call-saved XMM registers in order to generate wrong SEH unwind info. The attached fix makes sure that the frame pointer is always established after the fixed stack allocation by pointing it at or below the lowest used register save area, i.e. the SSE save area, and removing the special early saves in the prologue; the end result is a uniform prologue sequence for SEH whatever the frame size. And it avoids a discrepancy between cases where the number of saved general regs is even and cases where it is odd. gcc/ PR target/99234 * config/i386/i386.c (ix86_compute_frame_layout): For a SEH target, point the hard frame pointer to the SSE register save area instead of the general register save area. Perform only minimal adjustment for small frames if it is initially not correctly aligned. (ix86_expand_prologue): Remove early saves for a SEH target. * config/i386/winnt.c (struct seh_frame_state): Document constraint. gcc/testsuite/ * g++.dg/eh/seh-xmm-unwind.C: New test.
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
This directory contains the GNU Compiler Collection (GCC). The GNU Compiler Collection is free software. See the files whose names start with COPYING for copying permission. The manuals, and some of the runtime libraries, are under different terms; see the individual source files for details. The directory INSTALL contains copies of the installation information as HTML and plain text. The source of this information is gcc/doc/install.texi. The installation information includes details of what is included in the GCC sources and what files GCC installs. See the file gcc/doc/gcc.texi (together with other files that it includes) for usage and porting information. An online readable version of the manual is in the files gcc/doc/gcc.info*. See http://gcc.gnu.org/bugs/ for how to report bugs usefully. Copyright years on GCC source files may be listed using range notation, e.g., 1987-2012, indicating that every year in the range, inclusive, is a copyrightable year that could otherwise be listed individually.
Description
Languages
C++
31.9%
C
31.3%
Ada
12%
D
6.5%
Go
6.4%
Other
11.5%