I tested this with older gccs (like 2.95.2) and with a CVS snapshot from 02-04-2001, both display problems when -O1 is used. % g++ -v Reading specs from /mnt/image/install_egcs/bin/../lib/gcc-lib/i686-pc-linux-gnu/2.97/specs Configured with: ../egcs/configure --prefix=/export/home/mdejong/jazz/install_egcs --enable-shared --enable-haifa --enable-threads=posix --enable-languages=c,c++,java --enable-java-gc=boehm --enable-fast-character gcc version 2.97 20010204 (experimental) Release: gcc CVS (v3.0 branch), gcc 2.95.2 Environment: I ran into this bug on a Red Hat Linux 6.2 (Intel) box. How-To-Repeat: Compile without optimization, the compile with optimization to see the bug in action. % g++ -g -o foo foo.cc % ./foo OK % g++ -O1 -o foo foo.cc % ./foo ERROR : 40000000 80, should be 800000 80 When compiled with -O1, the following asm code is generated for Foo::bar() 1 0x8048620 <Foo::bar(unsigned&)>: push %ebp 2 0x8048621 <Foo::bar(unsigned&)+1>: mov %esp,%ebp 3 0x8048623 <Foo::bar(unsigned&)+3>: mov 0xc(%ebp),%eax 4 0x8048626 <Foo::bar(unsigned&)+6>: movl $0x800000,(%eax) 5 0x804862c <Foo::bar(unsigned&)+12>: mov $0x80,%eax 6 0x8048631 <Foo::bar(unsigned&)+17>: pop %ebp 7 0x8048632 <Foo::bar(unsigned&)+18>: ret The ptr %eax was 0xbffff4a0, printing out this memory before and after step 4 shows that it was changed from 0x40000000 to 0x00800000. The problem is, the memory written to does not seem to be the same memory location where the calling frame thinks a lives. The calling frame seems to keep a in the %ebx register, when returning from the function you can see that the original a has not been modified but the memory has. (gdb) printf "%x",a 40000000 (gdb) printf "%x",*0xbffff4a0 800000 (gdb) print &a Error: Address requested for identifier "a" which is in a register.
From: Eric Blake <ebb9@email.byu.edu> To: mdejong@redhat.com, gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org Cc: Subject: Re: c++/1920 Date: Fri, 09 Feb 2001 15:51:35 -0700 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1920&database=gcc Actually, it looks like this bug should be recategorized as accepts-illegal. Consider this variation: #include <stdio.h> void foo(unsigned &bar) { bar = 1; } int main() { unsigned a = 0; foo((unsigned) a); if (a == 1) printf("OK\n"); else { printf("a = %d, expeceted 1", a); return 1; } return 0; } $ g++ -o foo foo.cc foo.cc: In function `int main()': foo.cc:9: initialization of non-const reference type `unsigned int &' foo.cc:9: from rvalue of type `unsigned int' foo.cc:3: in passing argument 1 of `foo(unsigned int &)' Therefore, the fact that changing the declaration of a from unsigned to int allows the compiler to complete without warning or error is the true bug. In line 10, (unsigned) a is an rvalue, which cannot be assigned to the non-const unsigned & of foo(). The correct cast in this situation would be (unsigned &) a, which does work as expected. -- Eric Blake
State-Changed-From-To: open->analyzed State-Changed-Why: Eric Blake's analysis is correct.
From: Joe Buck <jbuck@synopsys.com> To: mdejong@redhat.com, gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org, ebb9@email.byu.edu Cc: Subject: Re: c++/1920 Date: Mon, 26 Feb 2001 15:02:39 -0800 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1920&database=gcc Eric's analysis is correct: this is not legal C++, and the bug is that neither gcc 2.95.2 nor CVS gcc issue any diagnostics. I've changed the status to "analyzed", "non-critical", "accepts-illegal" as Eric suggested. -- The reasonable man adapts himself to the world; the unreasonable man persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man. -----George Bernard Shaw
From: jbuck@synopsys.com To: gcc-gnats@gcc.gnu.org, mdejong@redhat.com, nobody@gcc.gnu.org Cc: Subject: Re: c++/1920 Date: 26 Feb 2001 23:00:53 -0000 Synopsis: g++ -O1 optimization bug in casting a reference argument State-Changed-From-To: open->analyzed State-Changed-By: jbuck State-Changed-When: Mon Feb 26 15:00:53 2001 State-Changed-Why: Eric Blake's analysis is correct. http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1920&database=gcc
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu> To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/1920: g++ -O1 optimization bug in casting a reference argument Date: Wed, 30 Oct 2002 20:03:32 -0600 (CST) The code in question invokes a gcc extension, casts as lvalues. The manual says about this: > Standard C++ allows compound expressions and conditional expressions > as lvalues, and permits casts to reference type, so use of this > extension is deprecated for C++ code. Still, if the compiler accepts the syntax, then it should get it right. W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ticam.utexas.edu www: http://www.ticam.utexas.edu/~bangerth
From: =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?= <martin@v.loewis.de> To: mdejong@redhat.com, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org Cc: Subject: Re: c++/1920: g++ -O1 optimization bug in casting a reference argument Date: Sun, 29 Dec 2002 00:02:26 +0100 Notice that the extension from (gcc)Lvalues explicitly rules out taking the address of a cast lvalue. Following the rationale for this restriction, I believe the extension should also not allow passing a cast lvalue as a reference. In addition, -pedantic should produce diagnostics if the extension is used. Regards, Martin
From: Wolfgang Bangerth <bangerth@ices.utexas.edu> To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/1920 Date: Mon, 5 May 2003 19:15:46 -0500 (CDT) Since 3.3, the programs also fails in non-optimized mode. I think it's all about not issuing a warning if a cast-as-lvalue is passed by reference. This extension is evil! W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
This has been fixed for c++ for 3.4. The reduced testcase has errors now: pr1920.cc: In function `int main()': pr1920.cc:9: error: could not convert `a' to `unsigned int&' pr1920.cc:3: error: in passing argument 1 of `void foo(unsigned int&)'
This is the meta-bug for the removal of cast-as-lvalue extension for c++.
*** Bug 1833 has been marked as a duplicate of this bug. ***
*** Bug 7884 has been marked as a duplicate of this bug. ***
*** Bug 10754 has been marked as a duplicate of this bug. ***
*** Bug 11748 has been marked as a duplicate of this bug. ***
What's the status here? Has cast-as-lvalue been removed from 3.4 yet or hasn't it?
cast-as-lvalue has not been removed from the mainline yet.
How does gcc3.4 fix this error, if cast-as-lvalue has not been removed yet? Will the gcc produce an error on compiling or generate appropriate code?
It was promised that this extension will be removed but who knows. 3.4 will reject the code that uses this. With this testcase: typedef char *pchar; void func(pchar &s) {} int main () { char *s = "123"; func((pchar)s); } the mainline (20030805) now ICEs: pr1833.2.cc: In function `int main()': pr1833.2.cc:9: internal compiler error: in convert_like_real, at cp/call.c:4131 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. Here is one which does not ICE but is accepted: extern int do_stuff(void *bar); int f(char *str) { void *foo; (char *) foo = str+1; return do_stuff(foo); } Here is another case where gcc ICEs: enum _t { off = 0, on = 100 }; void fn(int& x) { x = on; } int main() { _t t = off; fn((int)t); }
Subject: Re: no warning or error with cast-as-lvalue extension "pinskia at physics dot uc dot edu" <gcc-bugzilla@gcc.gnu.org> writes: | cast-as-lvalue has not been removed from the mainline yet. That is odd. I think we all agreed that it should go.
Subject: Re: no warning or error with cast-as-lvalue extension "markus dot breuer at materna dot de" <gcc-bugzilla@gcc.gnu.org> writes: | How does gcc3.4 fix this error, if cast-as-lvalue has not been removed yet? GCC-3.4 should just remove thta thingy.
*** Bug 8035 has been marked as a duplicate of this bug. ***
The two examples where I reported GCC ICEs, in 20030812, GCC no longer ICE but rejects them which is right.
Two more examples where the c front-end fails but the c++ frontend does not (this time inline-asm): int f(int i) { asm("":"+r"((short)i)); } int f1(int i) { asm("":"+r"((long long)i)); }
Removed target milestone; this is not a regression.
For the record: Deprecation of the cast-as-lvalue (mis-)feature has been discussed several times. The (presently) latest thread starts here: http://gcc.gnu.org/ml/gcc/2003-05/msg00847.html W.
Fixed in GCC 3.4 with: http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00191.html
*** Bug 19914 has been marked as a duplicate of this bug. ***