Bug 76773 - Stepping through conditional looks like it evaluates both halves
Summary: Stepping through conditional looks like it evaluates both halves
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.1 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-21 15:16 EDT by Nick Edgar CLA
Modified: 2005-02-16 12:58 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Edgar CLA 2004-10-21 15:16:45 EDT
build I20041013, VM: pj9n142-20040928a, using JXEs

- set a breakpoint in Perspective.getFastViewWidthRatio
- in target, opened a fast view
- breakpoint was hit
- stepped through it
- when I got to the conditional expression (a?b:c), it went into b, but when
that was done the line for c was highlighted (though it wasn't executed)
- I would have expected it to skip over the c part, or perhaps jump back and
highlight the assignment line

    private float getFastViewWidthRatio(String id) {
        ViewLayoutRec rec = getViewLayoutRec(id, true);
        if (rec.fastViewWidthRatio == IPageLayout.INVALID_RATIO) {
            IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry();
            String primaryId = ViewFactory.extractPrimaryId(id);
            IViewDescriptor desc = reg.find(primaryId);
            rec.fastViewWidthRatio = 
                (desc != null 
                    ? desc.getFastViewWidthRatio()
                    : IPageLayout.DEFAULT_FASTVIEW_RATIO);
        }
        return rec.fastViewWidthRatio;
    }

This may be a compiler bug, or perhaps even a VM bug, but thought I'd run it by
Debug first.
Comment 1 Luc Bourlier CLA 2004-10-21 17:54:08 EDT
It's a compiler problem. It's missing one row in the generated line number table.

smaller test case to see the problem reported by nick:

public class Bug_76773_1 {
  int a;
  public static void main(String[] args) {
    Bug_76773 a= new Bug_76773();
    a.a=
      a != null
        ? 0
        : 0;
  }
}

The important part is the assignment to the field.

The smallest test case I can create is :

public class Bug_76773 {
  int a;
  void foo() {
    a=
      1;
  }
}

The bytecode and line number table generated for foo() are:

void foo();
  Code:
   0:   aload_0
   1:   iconst_1
   2:   putfield        #18; //Field a:I
   5:   return
 
  LineNumberTable:
   line 4: 0
   line 5: 1
   line 6: 5
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      6      0    this       LBug_76773;


I think the line number table should be :
   line 5: 1
   line 4: 2
   line 6: 5

Comment 2 Olivier Thomann CLA 2004-10-21 19:12:52 EDT
I will investigate.
Comment 3 Olivier Thomann CLA 2005-02-04 15:40:54 EST
Luc,

The solution to get:
   line 5: 1
   line 4: 2
   line 6: 5

is not ideal. This means that when entering the method foo, you would jump
directly to the line with the "1" and then move back the the line with the "a"
and then move to the line with the closing brace.

I rather propose:
   line 4: 0
   line 5: 1
   line 4: 2
   line 6: 5

For the:
1:    a.a=
2:      a != null
3:        ? 0
4:        : 0;
This would result in:
line 1
line 2
line 3
line 1

Would this be an improvement?
Comment 4 Luc Bourlier CLA 2005-02-04 17:01:59 EST
mmm, i think it's what I meant ...
((i think i played a lot with different snippets of code, i think the line table
i gave is the one that should/would be generated if 'a' is a local variable))

The main point is, the instruction that does the assigment (store the value)
should be associated to the line which contains the '='. The line table you give
does that.
Comment 5 Olivier Thomann CLA 2005-02-04 17:06:12 EST
The main difference between our two line number table is that you would step
directly on the line that contains the '1' whereas I would first step on the
line that define the field.
I don't use the line of the '=', but rather the line that contains the field
name. My intuition is that you store the value in the field. The '=' is just the
assignment operator.
I don't believe that there is a perfect way to step through such code, but I
admit that stepping on the line that contains the false case of the conditional
doesn't look good.
Comment 6 Luc Bourlier CLA 2005-02-04 17:50:39 EST
Yes yes yes.
Stepping on the line that contains the field name, then stepping in the right
hand expression and stepping back on the field name is good and better than the
current behavior.
Comment 7 Olivier Thomann CLA 2005-02-04 23:29:19 EST
Fixed and released in HEAD.
Comment 8 David Audel CLA 2005-02-16 12:58:38 EST
Verified in I20050215-2300