bash-3.2$ cat g++.old-deja/g++.mike/warn1.C // { dg-do assemble } // { dg-options "-Wall" } typedef char * charptr; typedef __SIZE_TYPE__ size_t; char c[]={'A','B','C','D'}; int i=size_t(&c); int *pp=&i; void foo() { } int main() { charptr(*pp)++; // { dg-warning "" } return 0; } bash-3.2$ gcc -Wall -S -o /tmp/x.s g++.old-deja/g++.mike/warn1.C -m64 g++.old-deja/g++.mike/warn1.C: In function ‘int main()’: g++.old-deja/g++.mike/warn1.C:12: warning: value computed is not used bash-3.2$ gcc -Wall -S -o /tmp/x.s g++.old-deja/g++.mike/warn1.C -m32 g++.old-deja/g++.mike/warn1.C: In function ‘int main()’: g++.old-deja/g++.mike/warn1.C:12: error: lvalue required as increment operand bash-3.2$ On Linux/x86-64, I got FAIL: g++.old-deja/g++.mike/warn1.C (test for errors, line 12) FAIL: g++.old-deja/g++.mike/warn1.C (test for excess errors)
I tested with -m32 on powerpc64-linux, not with both -m32/-m64 which would have caught this; I'll test with both for related patches. The test previously used { dg-warning "" }, which matched any message from that line. The patch, in preparation to using new versions of dg-error and dg-warning that actually check for "warning" and "error", changed that to { dg-error "lvalue" }, which matches the error message for -m32 but not the warning message for -m64. It's a bug in the compiler that the error isn't reported for -m64, and the change to the test merely detected that. This should be a C++ bug, not a testsuite bug.
(In reply to comment #1) > I tested with -m32 on powerpc64-linux, not with both -m32/-m64 which would have > caught this; I'll test with both for related patches. > > The test previously used { dg-warning "" }, which matched any message from that > line. The patch, in preparation to using new versions of dg-error and > dg-warning that actually check for "warning" and "error", changed that to { > dg-error "lvalue" }, which matches the error message for -m32 but not the > warning message for -m64. It's a bug in the compiler that the error isn't > reported for -m64, and the change to the test merely detected that. > > This should be a C++ bug, not a testsuite bug. > I am not sure if it is a C++ bug. The differences between -m32 and -m64 are the sizes of __SIZE_TYPE__, int and pointer. Replace int with long gives me [hjl@gnu-6 tmp]$ cat x.cc typedef char * charptr; typedef __SIZE_TYPE__ size_t; char c[]={'A','B','C','D'}; long i=size_t(&c); long *pp=&i; void foo() { } int main() { charptr(*pp)++; // { dg-warning "" } return 0; } [hjl@gnu-6 tmp]$ gcc -Wall x.cc -S -m64 x.cc: In function ‘int main()’: x.cc:9: error: lvalue required as increment operand [hjl@gnu-6 tmp]$ gcc -Wall x.cc -S -m32 x.cc: In function ‘int main()’: x.cc:9: error: lvalue required as increment operand [hjl@gnu-6 tmp]$
This is twisting my brain, but in this simplified testcase: __PTRDIFF_TYPE__ p; short q; void foo () { ((char *)p)++; } void bar () { ((char *)q)++; } we get an error with both -m32 and-m64 for foo but not for bar: elm3b149% /home/janis/tools/gcc-trunk-anonsvn/bin/g++ -c -m32 z.C z.C: In function ‘void foo()’: z.C:3: error: lvalue required as increment operand elm3b149% /home/janis/tools/gcc-trunk-anonsvn/bin/g++ -c -m64 z.C z.C: In function ‘void foo()’: z.C:3: error: lvalue required as increment operand although the expression "(char *)q" in bar is not an lvalue. What am I missing?
The same thing happens in C for the simplified testcase; z.c is a copy of z.C from comment #3: elm3b149% /home/janis/tools/gcc-trunk-anonsvn/bin/gcc -c -m32 z.c z.c: In function ‘foo’: z.c:3: error: lvalue required as increment operand z.c: In function ‘bar’: z.c:4: warning: cast to pointer from integer of different size elm3b149% /home/janis/tools/gcc-trunk-anonsvn/bin/gcc -c -m64 z.c z.c: In function ‘foo’: z.c:3: error: lvalue required as increment operand z.c: In function ‘bar’: z.c:4: warning: cast to pointer from integer of different size
The operand of a postincrement and friends must be a modifiable lvalue. The type check code for both C and C++ calls get_unwidened, which removes the cast when it's a different size but leaves the cast when it's the same size. The later call to lvalue_p (via lvalue_or_else) says the operand is not an lvalue when there's still a cast, but doesn't complain when the cast has been removed.
This is a bug in the front-end ...
As all compilers starting with 4.0 behave the same way, this is not a new 4.4 regression.
Subject: Bug 37561 Author: jakub Date: Sat Nov 15 09:53:02 2008 New Revision: 141881 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141881 Log: PR c++/37561 * c-typeck.c (build_unary_op): Don't call get_unwidened. Use argtype instead of result_type. * typeck.c (cp_build_unary_op): Don't call get_unwidened. Use argtype instead of result_type. * gcc.dg/pr37561.c: New test. * g++.dg/other/increment1.C: New test. Added: trunk/gcc/testsuite/g++.dg/other/increment1.C trunk/gcc/testsuite/gcc.dg/pr37561.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-typeck.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk.
Thus fixed. No need to fix accepts-invalid bugs on release branches (IMHO we should never do that).
Subject: Bug 37561 Author: rguenth Date: Fri Jul 10 15:55:04 2009 New Revision: 149484 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149484 Log: 2009-07-10 Richard Guenther <rguenther@suse.de> Backport from mainline 2008-11-17 Jakub Jelinek <jakub@redhat.com> PR c++/36089 * init.c (constant_value_1): Handle TREE_LIST init. PR c++/37561 PR c++/36089 * g++.dg/template/init8.C: New test. Added: branches/gcc-4_3-branch/gcc/testsuite/g++.dg/template/init8.C Modified: branches/gcc-4_3-branch/gcc/cp/ChangeLog branches/gcc-4_3-branch/gcc/cp/init.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog