Bug 1920 - no warning or error with cast-as-lvalue extension
Summary: no warning or error with cast-as-lvalue extension
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.0
: P3 normal
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
: 1833 7884 8035 10754 11748 19914 (view as bug list)
Depends on:
Blocks:
 
Reported: 2001-02-09 01:26 UTC by mdejong
Modified: 2005-02-11 22:56 UTC (History)
11 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2003-08-06 01:50:42


Attachments
foo.cc (258 bytes, application/octet-stream)
2003-05-21 15:16 UTC, mdejong
Details

Note You need to log in before you can comment on or make changes to this bug.
Description mdejong 2001-02-09 01:26:01 UTC
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.
Comment 1 ebb9 2001-02-09 15:51:35 UTC
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
Comment 2 Joe Buck 2001-02-26 15:00:53 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Eric Blake's analysis is correct.
Comment 3 Joe Buck 2001-02-26 15:02:39 UTC
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

Comment 4 Joe Buck 2001-02-26 23:00:53 UTC
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

Comment 5 Wolfgang Bangerth 2002-10-30 20:03:32 UTC
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
 
 

Comment 6 martin 2002-12-29 00:02:26 UTC
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
 

Comment 7 Wolfgang Bangerth 2003-05-05 19:15:46 UTC
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/
Comment 8 Andrew Pinski 2003-05-23 04:04:42 UTC
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&)'
Comment 9 Andrew Pinski 2003-07-24 04:04:25 UTC
This is the meta-bug for the removal of cast-as-lvalue extension for c++.
Comment 10 Andrew Pinski 2003-07-24 04:05:21 UTC
*** Bug 1833 has been marked as a duplicate of this bug. ***
Comment 11 Andrew Pinski 2003-07-24 04:10:56 UTC
*** Bug 7884 has been marked as a duplicate of this bug. ***
Comment 12 Andrew Pinski 2003-07-24 04:11:27 UTC
*** Bug 10754 has been marked as a duplicate of this bug. ***
Comment 13 Andrew Pinski 2003-07-31 14:44:06 UTC
*** Bug 11748 has been marked as a duplicate of this bug. ***
Comment 14 Nathanael C. Nerode 2003-08-03 17:31:56 UTC
What's the status here?  Has cast-as-lvalue been removed from 3.4 yet or hasn't it?
Comment 15 Andrew Pinski 2003-08-06 01:50:41 UTC
cast-as-lvalue has not been removed from the mainline yet.
Comment 16 markus.breuer 2003-08-06 05:28:29 UTC
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?
Comment 17 Andrew Pinski 2003-08-06 05:41:28 UTC
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);
}
Comment 18 Gabriel Dos Reis 2003-08-06 07:34:13 UTC
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.
Comment 19 Gabriel Dos Reis 2003-08-06 07:34:47 UTC
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.

Comment 20 Andrew Pinski 2003-08-11 15:51:41 UTC
*** Bug 8035 has been marked as a duplicate of this bug. ***
Comment 21 Andrew Pinski 2003-08-12 12:48:17 UTC
The two examples where I reported GCC ICEs, in 20030812, GCC no longer ICE but rejects them 
which is right.
Comment 22 Andrew Pinski 2003-08-13 03:50:48 UTC
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));
}
Comment 23 Mark Mitchell 2003-09-01 01:23:01 UTC
Removed target milestone; this is not a regression.
Comment 24 Wolfgang Bangerth 2003-09-03 18:12:39 UTC
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. 
Comment 25 Mark Mitchell 2003-09-04 07:20:42 UTC
Fixed in GCC 3.4 with:

http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00191.html
Comment 26 Andrew Pinski 2005-02-11 22:56:08 UTC
*** Bug 19914 has been marked as a duplicate of this bug. ***