Bug 86813 - [compiler] step into switch statement locate wrong line
Summary: [compiler] step into switch statement locate wrong line
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0.1   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.2 RC1   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-28 05:37 EST by Evans Zhang CLA
Modified: 2006-04-13 13:00 EDT (History)
3 users (show)

See Also:


Attachments
Apply on HEAD (7.02 KB, patch)
2005-03-08 21:29 EST, 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 Evans Zhang CLA 2005-02-28 05:37:50 EST
when step into a switch statement, such as blow code fragment. I step by step,
so when step in the break, it should exit the switch, but it locate the cursor
line in the line commentted by step 3, and the assignment does not excute actually. 
If I add a blank default: statement, this bug do not occurs.

try {
switch {
case 1:
  f();         //step 1
  break;      //step 2 
case 2:
  f2();
  break;
  .
  .
  .
case 10:
  f10();
  x = false;   //step 3 
  break;
}
}catch(Exception e) {
}
Comment 1 Evans Zhang CLA 2005-02-28 05:42:33 EST
if the switch statement has no default substatement, when you debug step by
step, after excute the break  statement, it may locate wrong next highlight
line. I add a blank default substatement, this bug does not occur.
I use Eclipse 3.01 + eclipseme + wtk22 run on the jvm 1.5.0_01


Comment 2 Darin Wright CLA 2005-02-28 10:00:19 EST
Please investigate, Luc.
Comment 3 Luc Bourlier CLA 2005-03-04 17:43:36 EST
Smaller test case:

public class Bug_86813 {
  public static void main(String[] args) {
    boolean x= true;
    try {
      int i= 1;
      switch (i) { // <-- breakpoint here
        case 1:
          break;      //step 1 
        case 2:
          x = false;   //step 2 
          break;
      }
    }catch(Exception e) {
    }
  }
}

Reproducable on the latest I-build, jdt.core from HEAD, any VM.

The line table for the class is incomplete, but I'm not sure a correct line
table can be created for the generated code.
The line info for line 11 (the second break) is missing, but the problem is the
instruction for line 11 is also use for all other cases of the switch.

This is not a problem if the try-catch is removed.

Moving to JDT/Core.
Comment 4 Olivier Thomann CLA 2005-03-08 21:29:52 EST
Created attachment 18569 [details]
Apply on HEAD
Comment 5 Olivier Thomann CLA 2005-03-09 14:47:26 EST
Philippe, could you please review the patch? It improves the stepping on a
switch statement when the goto to the next bytecode has been optimized out.
Comment 6 Stefano Rocca CLA 2006-03-31 08:51:49 EST
Additional tests

TEST A

public class Bug_86813a {
	public static void main(String[] args) {
		int x = -1; // 1. breakpoint here
		try {
			int i = 4;
			switch (i) {
			case 1:
				x = 3;
				break;
			case 2:
				x = 4; // 2. jumps here
				break; // does not step here
			default:
			}
		} catch (Exception e) {
		}
		System.out.println(x); // 3. jumps here
		System.exit(0);
	}
}

The empty default statement does not resolve the problem.

TEST B

public class Bug_86813b {
	public static void main(String[] args) {
		int x = -1; // 1. breakpoint here
		try {
			int i = 4;
			switch (i) {
			case 1:
				x = 3;
				break;
			case 2:
				x = 4; 
				break; // 2. jumps here
			default:
				break; // does not step here
			}
		} catch (Exception e) {
		}
		
		System.out.println(x); // 3. jumps here
		System.exit(0);
	}
}

The default statement is apparently ignored

TEST C (correct)

public class Bug_86813c {
	public static void main(String[] args) {
		int x = -1; // 1. breakpoint here
		try {
			int i = 4;
			switch (i) {
			case 1:
				x = 3;
				break;
			case 2:
				x = 4; 
				break; 
			default:
                                x = 5; // 2. jumps here
			}
		} catch (Exception e) {
		}
		
		System.out.println(x); // 3. jumps here
		System.exit(0);
	}
}

Tested on Eclipse SDK Version: 3.1.2 Build id: M20060118-1600
Comment 7 Philipe Mulet CLA 2006-04-03 07:49:37 EDT
I don't think the patch is what we want here. 
Generated attribute & code for comment 3 is:
      Line numbers:
        [pc: 0, line: 3]
        [pc: 2, line: 5]
        [pc: 4, line: 6]
        [pc: 28, line: 8]
        [pc: 31, line: 10] // observe no entry in 33, hence entry for 31 is used
        [pc: 36, line: 13]
        [pc: 37, line: 15]

  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 1, Locals: 3
  public static void main(String[] args);
     0  iconst_1
     1  istore_1 [x]
     2  iconst_1
     3  istore_2 [i]
     4  iload_2 [i]
     5  tableswitch default: 33
          case 1: 28
          case 2: 31
    28  goto 33
    31  iconst_0
    32  istore_1 [x]
    33  goto 37
    36  astore_2
    37  return
      Exception Table:
        [pc: 2, pc: 36] -> 36 when : java.lang.Exception

When the goto next bytecode (end of switch) is optimized out, the goto from try block hasn't yet been generated; and when generated it does widen the last entry which is at pc 31 (second break). So no new entry is created for pc 33.

This issue should also occur in other situations (i.e. not optimized switch), as the widening may occur in all cases. Consider the following variation:
public class X {
  public static void main(String[] args) {
    boolean x= true;
    try {
      int i= 1; 
      if (i == 1) {
        i = 1;
      } else {
        i = 2;
      }
    }catch(Exception e) {
    }
  }
}

The stepping works fine, since the goto at end of THEN is actually chained to the  TRY block goto upon generation of the latter. This is not happening in switch case due to an issue in the branch chaining code, which isn't properly dealing with case labels.

By enabling the branch chaining to perform in all cases, the switch scenario is handled properly, and the resulting code is even better since chaining occurred.
Comment 8 Philipe Mulet CLA 2006-04-03 09:53:43 EDT
Added SwitchTest#test012.
Fixed
Comment 9 Maxime Daniel CLA 2006-04-13 13:00:54 EDT
Verified for 3.2 RC1 using Build id: I20060413-0010.
The original test case is fixed. Yet those of comment #6 aren't. Opened fup bug 136688.