Bug 49644 - [4.5 Regression] post-increment of promoted operand is incorrect.
Summary: [4.5 Regression] post-increment of promoted operand is incorrect.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.6.0
: P3 major
Target Milestone: 4.5.4
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
: 49933 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-07-05 15:34 UTC by Orion Poplawski
Modified: 2011-08-01 14:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.4.6, 4.6.2, 4.7.0
Known to fail: 4.5.2
Last reconfirmed: 2011-07-05 15:41:41


Attachments
gcc47-pr49644.patch (679 bytes, patch)
2011-07-07 09:54 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Orion Poplawski 2011-07-05 15:34:35 UTC
#include <stdio.h>
#include <complex.h>

int main(int argc, char *argv[]) {

 double data[6] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0},*d;
 double complex *c, s = 3.0 + 0.0I;
 int i;

 d=data;
 for (i = 0; i<6; i++) {
  printf("c(%p), d(%p)=%lf\n",c,d,*d);
  *c++ = *d++ * s;
 }
 return 0;
}


With gcc 4.4.5 (compiles without warnings with -Wall):
c(0x7fff16e86a00), d(0x7fff16e868d0)=1.000000
c(0x7fff16e86a10), d(0x7fff16e868d8)=2.000000
c(0x7fff16e86a20), d(0x7fff16e868e0)=3.000000
c(0x7fff16e86a30), d(0x7fff16e868e8)=4.000000
c(0x7fff16e86a40), d(0x7fff16e868f0)=5.000000
c(0x7fff16e86a50), d(0x7fff16e868f8)=6.000000

With gcc 4.5.1 and 4.6.0:
c(0x7fff5411f2f0), d(0x7fff5411f1c0)=1.000000
c(0x7fff5411f300), d(0x7fff5411f1d0)=3.000000
c(0x7fff5411f310), d(0x7fff5411f1e0)=5.000000
c(0x7fff5411f320), d(0x7fff5411f1f0)=0.000000
c(0x7fff5411f330), d(0x7fff5411f200)=0.000000
c(0x7fff5411f340), d(0x7fff5411f210)=0.000000

It appears that the right hand side  pointer is being incremented at the rate of its promoted size.  If you remove the " * s" from the increment line, the code works as expected.  Same problem with 32-bit and 64-bit machines.
Comment 1 Orion Poplawski 2011-07-05 15:41:08 UTC
May only apply to complex variables.  I can't reproduce with promotion of float to double.
Comment 2 Richard Biener 2011-07-05 15:41:41 UTC
The frontend generates

  *c++  = COMPLEX_EXPR <*d++  * REALPART_EXPR <SAVE_EXPR <s>>, *d++  * IMAGPART_EXPR <SAVE_EXPR <s>>>;

and thus increments d twice.
Comment 3 Jakub Jelinek 2011-07-05 19:46:30 UTC
The testcase looks wrong though, I don't see c being initialized anywhere.
Comment 4 Orion Poplawski 2011-07-05 20:01:27 UTC
Yeah, I screwed that up.  But it doesn't make any difference to the problem.  This should be correct though.

#include <stdio.h>
#include <complex.h>

int main(int argc, char *argv[]) {

 double data[6] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0},*d;
 double complex ddata[6], *c, s = 3.0;
 int i;

 d=data;
 c=ddata;
 for (i = 0; i<6; i++) {
  printf("c(%p), d(%p)=%f\n",c,d,*d);
  *c++ = *d++ * s;
 }
 return 0;
}
Comment 5 Jakub Jelinek 2011-07-07 09:54:13 UTC
Created attachment 24704 [details]
gcc47-pr49644.patch

Untested fix.
Comment 6 Orion Poplawski 2011-07-07 09:54:59 UTC
I am on vacation and will be out of the office until Thursay, July 21st.

Your message has been saved and I will respond if needed when I return.

If this is an urgent CoRA computing issue, please send email to
coracomputer@cora.nwra.com.

Cheers,

   Orion

--

Orion Poplawski
Technical Manager                     303-415-9701 x222
NWRA/CoRA Division                    FAX: 303-415-9702
3380 Mitchell Lane                  orion@cora.nwra.com
Boulder, CO 80301              http://www.cora.nwra.com
Comment 7 Jakub Jelinek 2011-07-07 19:11:29 UTC
Author: jakub
Date: Thu Jul  7 19:11:27 2011
New Revision: 176004

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176004
Log:
	PR c/49644
	* c-typeck.c (build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call c_save_expr on both
	operands.

	* gcc.c-torture/execute/pr49644.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr49644.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-typeck.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2011-07-07 19:14:41 UTC
Author: jakub
Date: Thu Jul  7 19:14:38 2011
New Revision: 176005

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176005
Log:
	PR c/49644
	* c-typeck.c (build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call c_save_expr on both
	operands.

	* gcc.c-torture/execute/pr49644.c: New test.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/gcc.c-torture/execute/pr49644.c
Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/c-typeck.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 9 Jakub Jelinek 2011-07-07 19:19:52 UTC
Fixed for C in 4.6+ so far, C++ patch is waiting for review.
Comment 10 Jakub Jelinek 2011-07-07 19:41:57 UTC
Author: jakub
Date: Thu Jul  7 19:41:55 2011
New Revision: 176006

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176006
Log:
	PR c/49644
	* typeck.c (cp_build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call save_expr on both
	operands.

	* g++.dg/torture/pr49644.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr49644.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
Comment 11 Jakub Jelinek 2011-07-07 19:43:03 UTC
Author: jakub
Date: Thu Jul  7 19:42:58 2011
New Revision: 176007

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176007
Log:
	PR c/49644
	* typeck.c (cp_build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call save_expr on both
	operands.

	* g++.dg/torture/pr49644.C: New test.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/torture/pr49644.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/typeck.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 12 Jakub Jelinek 2011-07-19 13:07:27 UTC
Author: jakub
Date: Tue Jul 19 13:07:23 2011
New Revision: 176456

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176456
Log:
	Backport from mainline
	2011-07-07  Jakub Jelinek  <jakub@redhat.com>

	PR c/49644
	* c-typeck.c (build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call c_save_expr on both
	operands.

	* gcc.c-torture/execute/pr49644.c: New test.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr49644.c
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/c-typeck.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Comment 13 Jakub Jelinek 2011-07-19 13:08:36 UTC
Author: jakub
Date: Tue Jul 19 13:08:33 2011
New Revision: 176457

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176457
Log:
	Backport from mainline
	2011-07-07  Jakub Jelinek  <jakub@redhat.com>

	PR c/49644
	* typeck.c (cp_build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
	one non-complex and one complex argument, call save_expr on both
	operands.

	* g++.dg/torture/pr49644.C: New test.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/torture/pr49644.C
Modified:
    branches/gcc-4_5-branch/gcc/cp/ChangeLog
    branches/gcc-4_5-branch/gcc/cp/typeck.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Comment 14 Jakub Jelinek 2011-07-19 13:48:36 UTC
Fixed.
Comment 15 Richard Biener 2011-08-01 14:50:17 UTC
*** Bug 49933 has been marked as a duplicate of this bug. ***