Bug 22581 - Ignore unreachable code for unread variables
Summary: Ignore unreachable code for unread variables
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: Other other
: P3 enhancement (vote)
Target Milestone: 2.1 M2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-08-20 12:25 EDT by Chris Beck CLA
Modified: 2002-10-17 10:38 EDT (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 Chris Beck CLA 2002-08-20 12:25:57 EDT
I would like to request a flag for compilation warnings.
We often have variables that are 
declared at the beginning of a function but only used within various conditional debug if {} 
blocks.
I would like (and I realize that this could be messy) a flag that allows the "unread 
variable" warning to understand that unreachable code in an if block is different from 
unreachable code after a return or exit or throw or whatever.
Comment 1 Philipe Mulet CLA 2002-10-02 06:06:11 EDT
Can you paste in a test case exposing the offending behavior ? I thought we 
were already making the distinction and not complaining about unread variables 
in unreachable code.
Comment 2 Philipe Mulet CLA 2002-10-02 06:24:14 EDT
*** Bug 23511 has been marked as a duplicate of this bug. ***
Comment 3 Philipe Mulet CLA 2002-10-02 06:27:08 EDT
Ignore previous comment, the mentionned PR is not a duplicate.
Comment 4 Chris Beck CLA 2002-10-04 17:29:30 EDT
Here is code that generates the warning.

public class Test {

	static final boolean DEBUG 
= false;
	
	private void doTest() {
		long time;
		if(DEBUG) time = 
System.currentTimeMillis();
		System.out.println("bob");
		if(DEBUG) 
System.out.println("Bob takes: " + (System.currentTimeMillis() - time) + " ms");
	}
}
Comment 5 Philipe Mulet CLA 2002-10-08 04:57:16 EDT
We already deal with the case the variable is declared in unreachable scope, 
but not in this very case.
Comment 6 Philipe Mulet CLA 2002-10-08 07:27:09 EDT
Support added to avoid reported fake used variables (treated as unused, just 
not reported).
Comment 7 Chris Beck CLA 2002-10-09 12:40:34 EDT
I thought that I would provide some extra information here.  I think my problem stems from the 
inability to differentiate between runtime and compile time.

Here are a bunch of examples 
that show what I am talking about:

/**
 * The criteria:
 * -differentiate runtime used from 
compile-time used
 * -differentiate conditionnally from definitely unreachable code.
 
*/
public class x {
	static final boolean FALSE = false;
	static final boolean TRUE = 
true;
	
	
	void unread1() {
		Object obj = "dummy";
		//obj reported as not runtime-
read because of shortcut OR below, although compiletime-used
		//cannot remove variable 
without impact for compile-time
		if (TRUE || obj != null) 
{
			doit(null);
		}
	}
	
	
	void unread2() {
		Object obj = "dummy";
		//obj 
reported as not runtime-used, although compiletime-used
		//cannot remove variable without 
impact for compile-time
		if (FALSE) {
			doit(obj);
		}
		
		if (false) 
{
			doit(obj);
		}
	}
	

	void unread3() {
		Object obj = "dummy";
		//obj 
reported as not runtime-used, and actually not compiletime-used 
too
		doit(null);
	}
	
	
	
	void unreachable1() {
		Object obj = 
"dummy";
		
		if (false) {
			doit(obj); //this is DEFINITELY unreachable code, but is 
not recognized as such
		}
		
		if (FALSE) {
			doit(obj); //this is conditionnally 
unreachable code, but is not recognized as such
		}
		
		
		while(false) 
{
			doit(obj); //this is DEFINITELY unreachable code, and is recognized as such, with 
error
		}
		
		while(FALSE) {
			doit(obj); //this is conditionnally unreachable 
code, but is recognized as definitely unreacheable code, with 
error
		}
		
		
		for(;false;) {
			doit(obj); //this is DEFINITELY unreachable 
code, but is recognized as definitely unreacheable code, with 
error
		}
		
		for(;FALSE;) {
			doit(obj); //this is conditionnally unreachable 
code, but is recognized as definitely unreacheable code, with error
		}
		
		int i = 
(false? doit("0") : doit("1")); //doit("0") is DEFINITELY unreachable code, but is not 
recognized as such
		
		int j = (FALSE? doit("0") : doit("1")); //doit("0") is 
conditionnally unreachable code, but is not recognized as such
	}


	void 
unreachable2() {
		Object obj = "dummy";
		//obj reported as not runtime-used, although 
compiletime-used
		//cannot remove variable without impact for compile-time
		
		if 
(TRUE) {
			throw new RuntimeException();
		}
		
		//since the variable is supposed to 
be unused,
		//how can this following code not be declared unreacheable?
		doit(obj); 
//this is conditionnally unreachable code
	}
	
	void unreachable3() {
		Object obj = 
"dummy";
		//obj reported as not runtime-used, although compiletime-used
		//cannot 
remove variable without impact for compile-time
		
		if (true) {
			throw new 
RuntimeException();
		}
		
		//since the variable is supposed to be unused,
		//how 
can this code not be declared unreacheable?
		doit(obj); //this is DEFINITELY unreachable 
code
	}


	//------------------
	
	int doit(Object obj) 
{
		System.out.println("hey"+obj);
		return obj==null?0:1;
	}

}
Comment 8 Philipe Mulet CLA 2002-10-10 07:25:29 EDT
With the released change (what you call conditionally unreachable is what we 
call fake reachable code - dead but cannot complain):
- unread1: no more complaint
- unread2: no more complaint
- unread3: 1 complaint: obj is never read
- unreachable1: 4 complaints
    1: obj is never read
    2: while(false) unreachable body
    3: while(false) unreachable body
    4: for(;false;) unreachable body
    5: for(;false;) unreachable body

    Note: I don't get why you expect 3 and 5 to not be problems. javac issues 
          them as well. Fake reachable code is only for if statements.

- unreachable2: no more complaint
- unreachable3: no more complaint

Closing, thanks for checking anyway. The mentionned fix will be released into 
next weekly integration build (20021015). I could give you a patch if it is 
really necessary.
Comment 9 Philipe Mulet CLA 2002-10-10 07:39:59 EDT
Oops, my previous comment for #unreachable1 is wrong. I am seeing 4 complaints:

- unreachable1: 4 complaints
    1: while(false) unreachable body
    2: while(false) unreachable body
    3: for(;false;) unreachable body
    4: for(;false;) unreachable body
Comment 10 Chris Beck CLA 2002-10-10 18:20:40 EDT
It is not that I don't expect 3&5 to be problems -- my issue is that I was hoping that eclipse would 
provide a little extra intelligence on top of javac.
I would like to distinguish between the 2 if 
statements.  One has the false keyword hard-coded, one uses a variable.  See, while I am in debug mode 
(_debug=true) it compiles cleanly, but when I change to _debug=false to check in to CVS my compile 
spawns warnings.  It's really just a question of wanting to have tidy code.  A warning that a method 
parameter is unused is useful, a warning that variables inside my debug code are unused is not 
useful.  Pedantic, I know :-)

boolean _debug = false;
int i = 0;
if (false) { 
System.out.println(i); }  // this should always be an error
if (_debug) { 
System.out.println(i); } // I would like to optionally mask this error
Comment 11 Philipe Mulet CLA 2002-10-11 06:21:47 EDT
The fact you use 'false' or a constant expression is equivalent from our 
compiler stand-point. The definite assignment/unassignment rules are pretty 
well spec'ed, we don't have the freedom to change them.

Now, we do provide this extra warning and could funace our implementation to 
meet this requirement, but the original complaint was the one I wanted to 
treat, since it could lead to discarding a variable which was truly referenced 
in unreachable code.
Comment 12 David Audel CLA 2002-10-17 10:38:09 EDT
Verified.