Bug 111898 - [compiler] Wrong code generation
Summary: [compiler] Wrong code generation
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1.2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 118417 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-10-07 10:24 EDT by Jacek CLA
Modified: 2006-02-20 07:20 EST (History)
2 users (show)

See Also:


Attachments
Proposed fix (917 bytes, patch)
2005-10-07 11:26 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix (1.03 KB, patch)
2005-10-07 11:30 EDT, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jacek CLA 2005-10-07 10:24:25 EDT
Run this code under Eclipse:

public class PostIncrementTest {
	public static void main(String[] args) {
		int a = 1;
	    a = a++;
		System.out.println("a="+a);
		
		int b = 1;
		System.out.println(b = b++);
		System.out.println("b="+b);
	}
}
Result is:
a=1
1
b=2

then compile and run this code using only javac and java commands, result is:
a=1
1
b=1
Comment 1 Olivier Thomann CLA 2005-10-07 10:33:34 EDT
Indeed it looks like we have a bug.
We tagged b = b++ as having no effect (with a warning), but we change its value.
I will check the bytecodes we produce.
Comment 2 Olivier Thomann CLA 2005-10-07 10:57:48 EDT
The problem comes from the optimization for the assignment has no effect.
In this case we generate the expression b++, but doing that this has a side
effect if b is reloaded afterwards.
And this is exactly what happens:`
     0  iconst_1
     1  istore_1 [a]
     2  getstatic java.lang.System.out : java.io.PrintStream [16]
     5  new java.lang.StringBuilder [22]
     8  dup
     9  ldc <String "a="> [24]
    11  invokespecial java.lang.StringBuilder(java.lang.String) [26]
    14  iload_1 [a]
    15  invokevirtual java.lang.StringBuilder.append(int) :
java.lang.StringBuilder [29]
    18  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [33]
    21  invokevirtual java.io.PrintStream.println(java.lang.String) : void [37]
    24  iconst_1
    25  istore_2 [b]
    26  getstatic java.lang.System.out : java.io.PrintStream [16]
    29  iload_2 [b]
    30  iinc 2 1 [b]  <===== increments b
    33  invokevirtual java.io.PrintStream.println(int) : void [42]
    36  getstatic java.lang.System.out : java.io.PrintStream [16]
    39  new java.lang.StringBuilder [22]
    42  dup
    43  ldc <String "b="> [45]
    45  invokespecial java.lang.StringBuilder(java.lang.String) [26]
    48  iload_2 [b] <===== reload b
    49  invokevirtual java.lang.StringBuilder.append(int) :
java.lang.StringBuilder [29]
    52  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [33]
    55  invokevirtual java.io.PrintStream.println(java.lang.String) : void [37]
    58  return

the case with a works fine, because no value is required, so we don't generate a++.

Philippe, we might want to turn the optimization off in case the expression is a
postfix expression or we generate the left hand side in this case.
Turning off the optimization fixed the issue.
Comment 3 Olivier Thomann CLA 2005-10-07 11:22:45 EDT
b = b++;
has no effect only if the assignment is complete generated. You need to assign
the value back in b after generating the right hand side not to have an effect
on b. Otherwise b has been incremented.
So I think we should change only the code gen and preserves the actual warning
for assignment with no effect.
Comment 4 Olivier Thomann CLA 2005-10-07 11:26:54 EDT
Created attachment 28029 [details]
Proposed fix

Apply on the org.eclipse.jdt.internal.compiler.ast package. It seems that the
patch wizard doesn't create unified patch anymore.
Comment 5 Olivier Thomann CLA 2005-10-07 11:30:54 EDT
Created attachment 28031 [details]
Proposed fix

Same patch, but this one can be applied directly on the project.
Comment 6 Philipe Mulet CLA 2005-10-10 06:29:13 EDT
In "b = b++", the assignment per se *has* some effect. It is nulling out the
effect of "b++". So as opposed to other cases where assignment has no effect,
the entire expression should be discarded. 

When value is still required, generating the lhs should suffice (no need to
perform entire assignment). However, I am rather enclined to disable the check
for this situation (which got added for bug 84480). Indeed, either we produce a
different problem description: expression has no effect; rather than just
assignment has no effect, since clients may be fooled into thinking they should
remove only the assignment from source, and leave "b++" in the code.

I don't think the code pattern is frequent enough it is worth it.

Fixed, added AssignmentTest#test039, tuned Assignment#test035.
Comment 7 Philipe Mulet CLA 2005-10-10 06:59:47 EDT
Backported to 3.1.maintenance (> 3.1.1)
Comment 8 Olivier Thomann CLA 2005-11-29 09:51:14 EST
*** Bug 118417 has been marked as a duplicate of this bug. ***
Comment 9 Olivier Thomann CLA 2005-12-13 10:09:43 EST
Verified for 3.2M4 in I20051212-2000
Comment 10 Olivier Thomann CLA 2006-01-09 11:00:20 EST
Verified for 3.1.2 in M20060109-0800.
Comment 11 Philipe Mulet CLA 2006-02-20 07:20:19 EST
Note that "a = ++a" could still be complained against.
Added note to bug 100369