From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31356 invoked by alias); 17 Oct 2003 23:54:22 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 31349 invoked by uid 48); 17 Oct 2003 23:54:21 -0000 Date: Sat, 18 Oct 2003 00:15:00 -0000 From: "mdorey at bluearc dot com" To: gcc-bugs@gcc.gnu.org Message-ID: <20031017235414.12667.mdorey@bluearc.com> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c++/12667] New: max(enum) returns reference to temporary X-Bugzilla-Reason: CC X-SW-Source: 2003-10/txt/msg01442.txt.bz2 List-Id: PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12667 Summary: max(enum) returns reference to temporary Product: gcc Version: 3.3.2 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mdorey at bluearc dot com CC: gcc-bugs at gcc dot gnu dot org I think that max1() and max2() are both legal and should generate equivalent, legal code: enum E { E1, E2 }; const E& max1(const E& a, const E& b) { bool c = a < b; return c ? b : a; } const E& max2(const E& a, const E& b) { return a < b ? b : a; } max2(), however, provokes a warning: max-enum.cpp: In function `const E& max2(const E&, const E&)': max-enum.cpp:9: warning: returning reference to temporary And, worse, the warning's accurate in that, I think, incorrect code is generated. I'm a PowerPC weenie at the moment, so this is the clearest demonstration of the problem in my eyes (3.3.1 sadly): trevithick:~/playpen$ powerpc-eabi-g++ -W -Wall -pedantic -v -O2 -c max- enum.cpp Reading specs from /usr/local/lib/gcc-lib/powerpc-eabi/3.3.1/specs Configured with: ../gcc-3.3.1/configure --target=powerpc-eabi --with-newlib -- with-local-prefix=/usr/local/powerpc-eabi --enable-languages=c,c++ --enable-cxx- flags=-fno-exceptions Thread model: single gcc version 3.3.1 /usr/local/lib/gcc-lib/powerpc-eabi/3.3.1/cc1plus -quiet -v -D__GNUC__=3 - D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=1 max-enum.cpp -D__GNUG__=3 -quiet - dumpbase max-enum.cpp -auxbase max-enum -O2 -W -Wall -pedantic -version - o /tmp/cchuQIuU.s GNU C++ version 3.3.1 (powerpc-eabi) compiled by GNU C version 3.3.1 (Debian). GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=129171 ignoring nonexistent directory "NONE/include" ignoring nonexistent directory "/usr/local/powerpc-eabi/sys-include" ignoring nonexistent directory "/usr/local/powerpc-eabi/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include/c++/3.3.1 /usr/local/include/c++/3.3.1/powerpc-eabi /usr/local/include/c++/3.3.1/backward /usr/local/lib/gcc-lib/powerpc-eabi/3.3.1/include End of search list. max-enum.cpp: In function `const E& max2(const E&, const E&)': max-enum.cpp:9: warning: returning reference to temporary /usr/local/lib/gcc-lib/powerpc-eabi/3.3.1/../../../../powerpc-eabi/bin/as - mppc -V -Qy -o max-enum.o /tmp/cchuQIuU.s GNU assembler version 2.14 (powerpc-eabi) using BFD version 2.14 20030612 trevithick:~/playpen$ powerpc-eabi-objdump --disassemble max-enum.o max-enum.o: file format elf32-powerpc Disassembly of section .text: 00000000 <_Z4max1RK1ES1_>: 0: 81 23 00 00 lwz r9,0(r3) 4: 7c 6b 1b 78 mr r11,r3 8: 80 04 00 00 lwz r0,0(r4) c: 7c 83 23 78 mr r3,r4 10: 7c 09 00 00 cmpw r9,r0 14: 4d 80 00 20 bltlr 18: 7d 63 5b 78 mr r3,r11 1c: 4e 80 00 20 blr 00000020 <_Z4max2RK1ES1_>: 20: 94 21 ff f0 stwu r1,-16(r1) 24: 38 61 00 08 addi r3,r1,8 28: 38 21 00 10 addi r1,r1,16 2c: 4e 80 00 20 blr trevithick:~/playpen$ But the problem is also exhibited in the unoptimised build (I can follow-up with the disassembly if you like) and in 3.3.2 Intel builds: trevithick:~/playpen$ g++ -W -Wall -pedantic -v -O2 -c max-enum.cpp Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.2/specs Configured with: ../src/configure -v --enable- languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr -- mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include- dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib --enable-nls -- without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable- debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux Thread model: posix gcc version 3.3.2 20031005 (Debian prerelease) /usr/lib/gcc-lib/i486-linux/3.3.2/cc1plus -quiet -v -D__GNUC__=3 - D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=2 -D_GNU_SOURCE max-enum.cpp - D__GNUG__=3 -quiet -dumpbase max-enum.cpp -auxbase max-enum -O2 -W -Wall - pedantic -version -o /tmp/ccyKxhqp.s GNU C++ version 3.3.2 20031005 (Debian prerelease) (i486-linux) compiled by GNU C version 3.3.2 20031005 (Debian prerelease). GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=129171 ignoring nonexistent directory "/usr/i486-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/include/c++/3.3 /usr/include/c++/3.3/i486-linux /usr/include/c++/3.3/backward /usr/local/include /usr/lib/gcc-lib/i486-linux/3.3.2/include /usr/include End of search list. max-enum.cpp: In function `const E& max2(const E&, const E&)': max-enum.cpp:9: warning: returning reference to temporary as -V -Qy -o max-enum.o /tmp/ccyKxhqp.s GNU assembler version 2.14.90.0.6 (i386-linux) using BFD version 2.14.90.0.6 20030820 Debian GNU/Linux trevithick:~/playpen$ objdump --disassemble max-enum.o max-enum.o: file format elf32-i386 Disassembly of section .text: 00000000 <_Z4max1RK1ES1_>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 55 0c mov 0xc(%ebp),%edx 6: 8b 4d 08 mov 0x8(%ebp),%ecx 9: 8b 02 mov (%edx),%eax b: 39 01 cmp %eax,(%ecx) d: 7d 04 jge 13 <_Z4max1RK1ES1_+0x13> f: 89 d0 mov %edx,%eax 11: 5d pop %ebp 12: c3 ret 13: 89 c8 mov %ecx,%eax 15: eb fa jmp 11 <_Z4max1RK1ES1_+0x11> 17: 90 nop 18: 90 nop 19: 8d b4 26 00 00 00 00 lea 0x0(%esi,1),%esi 00000020 <_Z4max2RK1ES1_>: 20: 55 push %ebp 21: 89 e5 mov %esp,%ebp 23: 83 ec 04 sub $0x4,%esp 26: 89 ec mov %ebp,%esp 28: 8d 45 fc lea 0xfffffffc(%ebp),%eax 2b: 5d pop %ebp 2c: c3 ret 2d: 90 nop 2e: 89 f6 mov %esi,%esi trevithick:~/playpen$ The problem doesn't happen if E is typedef()d to be int.