From mboxrd@z Thu Jan 1 00:00:00 1970 From: snyder@fnal.gov To: gcc-gnats@gcc.gnu.org Subject: c++/4026: bad code generated with optimization Date: Tue, 14 Aug 2001 20:16:00 -0000 Message-id: <200108150304.f7F34AP21636@karma.fnal.gov> X-SW-Source: 2001-08/msg00408.html List-Id: >Number: 4026 >Category: c++ >Synopsis: bad code generated with optimization >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Tue Aug 14 20:16:00 PDT 2001 >Closed-Date: >Last-Modified: >Originator: scott snyder >Release: 3.0.1 20010813 (prerelease) >Organization: >Environment: System: Linux karma 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ../egcs/configure --prefix=/usr/local/egcs --enable-threads=posix --enable-long-long >Description: The program below crashes when compiled with -O2: $ g++ -O2 -o x x.cc $ ./x aa: bfffca70 123 aa: bfffca50 123 Segmentation fault (core dumped) $ Without -O2, it executes correctly: $ g++ -o x x.cc $ ./x aa: bfffca80 123 aa: bfffca50 123 bb bfffca50 123 bb bfffca80 123 $ The problem also goes away if -fno-strict-aliasing is used. I see the problem already in the 00.rtl dump, so the problem is in the front- or middle-end, not the backend. I do not see this problem with gcc 2.95, so this is a regression from that version. It is, however, present in gcc 3.0. Here's a condensed version of the initial RTL output for main() (in hopefully obvious notation, omitting exception handling code that is not normally reached): 8 $esp = $esp & ~0x0f 10 $42 = 0 12 $esp = $esp - $42 ;; Set up temp1 --- located at offset -32 14 $43 = $virtual-stack-dynamic 27 $44 = $virtual-stack-vars - 32 33 $45 = $44 42 $46 = $45 + 4 48 *$46 = 0 52 *($46 + 12) = 0 65 $esp = $esp - 12 67 *(--$esp) = $45 68 call initialize_map 70 $esp += 16 121 $53 = &$52 ;; Make the temporary copy of temp1 to pass to yyy --- ;; located at offset -64 125 $54 = $virtual-stack-vars - 64 127 $55 = $virtual-stack-vars - 32 133 $56 = $54 142 $57 = $56 + 4 148 *$57 = 0 152 *($57 + 12) = 0 168 $esp -= 12 170 *(--$esp) = $56 171 call initialize_map 173 $esp += 16 ;; Call yyy. Not sure about the value that's getting passed; looks ;; like it's uninitialized? 235 $esp -= 12 237 *(--$esp) = &$52 238 call yyy 241 $esp += 16 ;; Start executing the dtor for the temporary at - 64. ;; ~deque() { ;; _Deque_iterator i = _M_start; ;; } ;; Copy _M_start to i, where i is at offset - 48. ;; ;; __BUT__ the temporary at -64 is _20_ bytes long --- ;; so this overwrites the last word of the temporary! 328 $67 = $virtual-stack-vars - 64 343 $68 = $virtual-stack-vars - 48 345 $69 = $67 + 4 352 $70 = *$69 354 *$68 = $70 358 $71 = *($69 + 12) 360 *($68 + 12) = $71 376 $esp -= 12 378 *(--$esp) = $67 379 call ~Deque_base 381 $esp += 16 ;; Start executing the dtor for temp1 at - 32. 481 $80 = $virtual-stack-vars - 32 496 $81 = $virtual-stack-vars - 48 498 $82 = $80 + 4 505 $83 = *$82 507 *$81 = $83 511 $84 = *($82 + 12) 513 *($81 + 12) = $84 529 $esp -= 12 531 *(--$esp) = $80 532 call ~Deque_base 534 $esp += 16 ;; Return. 387 $eax = 0 >How-To-Repeat: Compile with -O2: ---------------------------------------------------------------- extern "C" int printf (...); struct _Deque_iterator { int _M_cur; int x[2]; int* _M_node; _Deque_iterator() : _M_cur(0), _M_node(0) {} _Deque_iterator(const _Deque_iterator& __x) : _M_cur(__x._M_cur), _M_node(__x._M_node) {} }; class _Deque_base { public: int yy; _Deque_base() : _M_start() { _M_initialize_map(); } ~_Deque_base(); void _M_initialize_map(); _Deque_iterator _M_start; }; _Deque_base::~_Deque_base() { printf ("bb %x %x\n", this, *_M_start._M_node); } void _Deque_base::_M_initialize_map() { yy = 0x123; printf ("aa: %x %x\n", this, yy); _M_start._M_node = &yy; _M_start._M_cur = yy; } class deque : protected _Deque_base { public: deque () {} deque(const deque& __x) {} ~deque() { _Deque_iterator i = _M_start; } }; class GeometryAddress { public: GeometryAddress(deque addressStack) {} }; void yyy (const GeometryAddress& gb) { } int main() { deque temp1; yyy (GeometryAddress (temp1)); return 0; } ---------------------------------------------------------------- >Fix: >Release-Note: >Audit-Trail: >Unformatted: