update to v_B42
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 9eee7ac..2f84dd9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -3404,7 +3404,7 @@
break;
case 'e' :
if (token.equals("enumSwitch") //$NON-NLS-1$
- || token.equals("incomplete-switch")) { //$NON-NLS-1$
+ || token.equals("incomplete-switch") /*backward compatible*/) { //$NON-NLS-1$
setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
return;
} else if (token.equals("emptyBlock")) {//$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 81297f5..708afb8 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,7 +1,7 @@
#Format: compiler.name = word1 word2 word3
compiler.name = Eclipse Compiler for Java(TM)
#Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.B39, 3.7.0 M6
+compiler.version = 0.B42, 3.7.0 M6
compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
###{ObjectTeams:
@@ -303,7 +303,6 @@
\ maskedCatchBlock\n\
\ includeAssertNull raise null warnings for variables\n\
\ that got tainted in an assert expression\n\
-\ incomplete-switch same as enumSwitch\n\
\ indirectStatic indirect reference to static member\n\
\ inferredcallout + a callout binding has to be inferred (OTJLD 3.1(j))\n\
\ intfAnnotation + annotation type used as super interface\n\
@@ -338,6 +337,8 @@
\ syntheticAccess synthetic access for innerclass\n\
\ tasks(<tags separated by |>) tasks identified by tags inside comments\n\
\ typeHiding + type parameter hiding another type\n\
+\ unavoidableGenericProblems + ignore unavoidable type safety problems\n\
+\ due to raw APIs\n\
\ unchecked + unchecked type operation\n\
\ unnecessaryElse unnecessary else clause\n\
\ unqualifiedField unqualified reference to field\n\
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index cf7c3ea..d0595dd 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -41,11 +41,62 @@
</td>
</tr>
</table>
+<a name="v_B42"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 9, 2011 - 3.7.0 M6
+<br>Project org.eclipse.jdt.core v_B42
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B42">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250">339250</a>
+[null] Incorrect redundant null check warning on a String
+
+<a name="v_B41"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 8, 2011
+<br>Project org.eclipse.jdt.core v_B41
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B41">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339139">339139</a>
+[compiler] HEAD contents of org.eclipse.wst.jsdt.core doesn't compile anymore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649">338649</a>
+[perfs] Regression on FullSourceWorkspaceModelTests#testInitJDTPlugin
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339128">339128</a>
+[Doc] Sort statements and expressions inside DOM documentation for both abstract classes org.eclipse.jdt.core.dom.Expressionn and org.eclipse.jdt.core.dom.Statement
+
+<a name="v_B40"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 6, 2011
+<br>Project org.eclipse.jdt.core v_B40
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B40">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950">326950</a>
+[compiler][null]Do not optimize code generation based on static analysis (dead code)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324178">324178</a>
+[null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006">338006</a>
+IJavaProject#getPackageFragmentRoots() should return roots in order
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234">338234</a>
+[compiler] Missing warning for uninitialized variable in dead code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336428">336428</a>
+[compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+
<a name="v_B39"></a>
<hr><h1>
Eclipse Platform Build Notes<br>
Java development tools core</h1>
-Eclipse SDK 3.7M6 - March 1, 2011 - 3.7.0 M6
+Eclipse SDK 3.7M6 - March 1, 2011
<br>Project org.eclipse.jdt.core v_B39
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B39">cvs</a>).
<h2>What's new in this drop</h2>
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
index f1804a5..ce3da94 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -57,7 +57,7 @@
if (isLeftOptimizedFalse) {
if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
currentScope.problemReporter().fakeReachable(this.right);
- rightInfo.setReachMode(FlowInfo.UNREACHABLE);
+ rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
}
rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index efe1e15..9c4213f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -238,7 +238,7 @@
* exact need.
*/
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
// perform some emulation work in case there is some and we are inside a local type only
@@ -257,7 +257,7 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
// if constructor from parameterized type got found, use the original constructor at codegen time
MethodBinding codegenBinding = this.binding.original();
//{ObjectTeams: baseclass decapsulation:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index 12d989b..efef338 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -56,7 +56,7 @@
UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits();
FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse();
if (isOptimizedTrueAssertion) {
- assertInfo.setReachMode(FlowInfo.UNREACHABLE);
+ assertInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (this.exceptionArgument != null) {
@@ -174,7 +174,7 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
// need assertion flag: $assertionsDisabled on outer most source clas
// (in case of static member of interface, will use the outermost static member - bug 22334)
SourceTypeBinding outerMostClass = currentScope.enclosingSourceType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index 17f0b30..f03028c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -69,7 +69,7 @@
FlowInfo.DEAD_END);
// check for missing returning path
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.NeedFreeReturn;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index e323760..03ab69a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -42,7 +42,18 @@
if (this.resolvedType.id != T_JavaLangString) {
this.lhs.checkNPE(currentScope, flowContext, flowInfo);
}
- return ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+ flowInfo = ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+ if (this.resolvedType.id == T_JavaLangString) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250
+ LocalVariableBinding local = this.lhs.localVariableBinding();
+ if (local != null && this.resolvedType.id == T_JavaLangString) {
+ // compound assignment results in a definitely non null value for String
+ flowInfo.markAsDefinitelyNonNull(local);
+ if (flowContext.initsOnFinally != null)
+ flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
+ }
+ }
+ return flowInfo;
}
public boolean checkCastCompatibility() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index a911720..ac2a48b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -8,7 +8,10 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephen Herrmann <stephan@cs.tu-berlin.de> - Contributions for bugs 133125, 292478
+ * Stephen Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ * bug 133125 - [compiler][null] need to report the null status of expressions and analyze them simultaneously
+ * bug 292478 - Report potentially null across variable assignment
+ * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
*******************************************************************************/
@@ -40,6 +43,9 @@
int trueInitStateIndex = -1;
int falseInitStateIndex = -1;
int mergedInitStateIndex = -1;
+
+ // we compute and store the null status during analyseCode (https://bugs.eclipse.org/324178):
+ private int nullStatus = FlowInfo.UNKNOWN;
public ConditionalExpression(
Expression condition,
@@ -66,7 +72,7 @@
FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy();
if (isConditionOptimizedFalse) {
if ((mode & FlowInfo.UNREACHABLE) == 0) {
- trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+ trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel);
@@ -79,7 +85,7 @@
FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy();
if (isConditionOptimizedTrue) {
if ((mode & FlowInfo.UNREACHABLE) == 0) {
- falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+ falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel);
@@ -92,10 +98,30 @@
FlowInfo mergedInfo;
if (isConditionOptimizedTrue){
mergedInfo = trueFlowInfo.addPotentialInitializationsFrom(falseFlowInfo);
+ this.nullStatus = this.valueIfTrue.nullStatus(trueFlowInfo);
} else if (isConditionOptimizedFalse) {
mergedInfo = falseFlowInfo.addPotentialInitializationsFrom(trueFlowInfo);
+ this.nullStatus = this.valueIfFalse.nullStatus(falseFlowInfo);
} else {
- // if ((t && (v = t)) ? t : t && (v = f)) r = v; -- ok
+ // this block must meet two conflicting requirements (see https://bugs.eclipse.org/324178):
+ // (1) For null analysis of "Object o2 = (o1 != null) ? o1 : new Object();" we need to distinguish
+ // the paths *originating* from the evaluation of the condition to true/false respectively.
+ // This is used to determine the possible null status of the entire conditional expression.
+ // (2) For definite assignment analysis (JLS 16.1.5) of boolean conditional expressions of the form
+ // "if (c1 ? expr1 : expr2) use(v);" we need to check whether any variable v will be definitely
+ // assigned whenever the entire conditional expression evaluates to true (to reach the then branch).
+ // I.e., we need to collect flowInfo *towards* the overall outcome true/false
+ // (regardless of the evaluation of the condition).
+
+ // to support (1) use the infos of both branches originating from the condition for computing the nullStatus:
+ computeNullStatus(trueFlowInfo, falseFlowInfo);
+
+ // to support (2) we split the true/false branches according to their inner structure. Consider this:
+ // if (b ? false : (true && (v = false))) return v; -- ok
+ // - expr1 ("false") has no path towards true (mark as unreachable)
+ // - expr2 ("(true && (v = false))") has a branch towards true on which v is assigned.
+ // -> merging these two branches yields: v is assigned
+ // - the paths towards false are irrelevant since the enclosing if has no else.
cst = this.optimizedIfTrueConstant;
boolean isValueIfTrueOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
boolean isValueIfTrueOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
@@ -104,26 +130,26 @@
boolean isValueIfFalseOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
boolean isValueIfFalseOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
- UnconditionalFlowInfo trueInfoWhenTrue = trueFlowInfo.initsWhenTrue().unconditionalCopy();
- UnconditionalFlowInfo falseInfoWhenTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
- UnconditionalFlowInfo trueInfoWhenFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
- UnconditionalFlowInfo falseInfoWhenFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
+ UnconditionalFlowInfo trueFlowTowardsTrue = trueFlowInfo.initsWhenTrue().unconditionalCopy();
+ UnconditionalFlowInfo falseFlowTowardsTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
+ UnconditionalFlowInfo trueFlowTowardsFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
+ UnconditionalFlowInfo falseFlowTowardsFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
if (isValueIfTrueOptimizedFalse) {
- trueInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
+ trueFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (isValueIfFalseOptimizedFalse) {
- falseInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
+ falseFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (isValueIfTrueOptimizedTrue) {
- trueInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
+ trueFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (isValueIfFalseOptimizedTrue) {
- falseInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
+ falseFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
mergedInfo =
FlowInfo.conditional(
- trueInfoWhenTrue.mergedWith(falseInfoWhenTrue),
- trueInfoWhenFalse.mergedWith(falseInfoWhenFalse));
+ trueFlowTowardsTrue.mergedWith(falseFlowTowardsTrue),
+ trueFlowTowardsFalse.mergedWith(falseFlowTowardsFalse));
}
this.mergedInitStateIndex =
currentScope.methodScope().recordInitializationStates(mergedInfo);
@@ -131,6 +157,30 @@
return mergedInfo;
}
+ private void computeNullStatus(FlowInfo trueBranchInfo, FlowInfo falseBranchInfo) {
+ // given that the condition cannot be optimized to a constant
+ // we now merge the nullStatus from both branches:
+ int ifTrueNullStatus = this.valueIfTrue.nullStatus(trueBranchInfo);
+ int ifFalseNullStatus = this.valueIfFalse.nullStatus(falseBranchInfo);
+
+ if (ifTrueNullStatus == ifFalseNullStatus) {
+ this.nullStatus = ifTrueNullStatus;
+ return;
+ }
+ // is there a chance of null (or non-null)? -> potentially null etc.
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
+ int status = 0;
+ int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
+ if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
+ status |= FlowInfo.POTENTIALLY_NULL;
+ if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+ status |= FlowInfo.POTENTIALLY_NON_NULL;
+ if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
+ status |= FlowInfo.POTENTIALLY_UNKNOWN;
+ if (status > 0)
+ this.nullStatus = status;
+ }
+
/**
* Code generation for the conditional operator ?:
*
@@ -320,33 +370,9 @@
codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
}
-public int nullStatus(FlowInfo flowInfo) {
- Constant cst = this.condition.optimizedBooleanConstant();
- if (cst != Constant.NotAConstant) {
- if (cst.booleanValue()) {
- return this.valueIfTrue.nullStatus(flowInfo);
- }
- return this.valueIfFalse.nullStatus(flowInfo);
+ public int nullStatus(FlowInfo flowInfo) {
+ return this.nullStatus;
}
- int ifTrueNullStatus = this.valueIfTrue.nullStatus(flowInfo),
- ifFalseNullStatus = this.valueIfFalse.nullStatus(flowInfo);
- if (ifTrueNullStatus == ifFalseNullStatus) {
- return ifTrueNullStatus;
- }
- // is there a chance of null (or non-null)? -> potentially null etc.
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
- int status = 0;
- int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
- if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
- status |= FlowInfo.POTENTIALLY_NULL;
- if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
- status |= FlowInfo.POTENTIALLY_NON_NULL;
- if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
- status |= FlowInfo.POTENTIALLY_UNKNOWN;
- if (status > 0)
- return status;
- return FlowInfo.UNKNOWN;
-}
public Constant optimizedBooleanConstant() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index d01c4c4..d6e26ae 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -282,7 +282,7 @@
}
}
// check for missing returning path
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.NeedFreeReturn;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
index cf09127..5806ce8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -72,7 +72,7 @@
// code generation can be optimized when no need to continue in the loop
if ((actionInfo.tagBits &
loopingContext.initsOnContinue.tagBits &
- FlowInfo.UNREACHABLE) != 0) {
+ FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.continueLabel = null;
}
if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 2036f58..80d7e35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -273,7 +273,7 @@
void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
ReferenceBinding superTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
// perform some emulation work in case there is some and we are inside a local type only
if (superTypeErasure.isNestedType()
&& currentScope.enclosingSourceType().isLocalType()) {
@@ -289,7 +289,7 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
// if constructor from parameterized type got found, use the original constructor at codegen time
MethodBinding codegenBinding = this.binding.original();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index eba9092..6032875 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -490,7 +490,7 @@
* No need to emulate access to protected fields since not implicitly accessed
*/
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
//{ObjectTeams: don't create (more) synthetics for base field accessed via callout:
if ( FieldModel.isCalloutAccessed(this.binding)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index 86593c7..7f0b9b1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -136,7 +136,7 @@
} else {
actionInfo = initsWhenTrue.unconditionalCopy();
if (isConditionOptimizedFalse){
- actionInfo.setReachMode(FlowInfo.UNREACHABLE);
+ actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
}
if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
@@ -146,7 +146,7 @@
// code generation can be optimized when no need to continue in the loop
if ((actionInfo.tagBits &
loopingContext.initsOnContinue.tagBits &
- FlowInfo.UNREACHABLE) != 0) {
+ FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.continueLabel = null;
}
else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 711fde8..3a7b16c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -121,7 +121,7 @@
addInitializationsFrom(condInfo.initsWhenFalse());
// TODO (maxime) no need to test when false: can optimize (same for action being unreachable above)
if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits &
- FlowInfo.UNREACHABLE) != 0) {
+ FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.continueLabel = null;
} else {
actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
index 3e996d6..7d0788e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -67,11 +67,11 @@
// process the THEN part
FlowInfo thenFlowInfo = conditionFlowInfo.safeInitsWhenTrue();
if (isConditionOptimizedFalse) {
- thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+ thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
FlowInfo elseFlowInfo = conditionFlowInfo.initsWhenFalse().copy();
if (isConditionOptimizedTrue) {
- elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+ elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
if (((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) &&
((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)) {
@@ -99,7 +99,7 @@
thenFlowInfo = this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
}
// code gen: optimizing the jump around the ELSE part
- if ((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) {
+ if ((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.bits |= ASTNode.ThenExit;
}
@@ -167,10 +167,7 @@
if (hasThenPart) {
BranchLabel falseLabel = null;
// generate boolean condition only if needed
- if (((this.bits & ASTNode.IsElseStatementUnreachable) != 0) ||
- (cst != Constant.NotAConstant && cst.booleanValue() == true)) {
- // No need to generate if condition statement when we know that only the then action
- // will be executed
+ if (cst != Constant.NotAConstant && cst.booleanValue() == true) {
this.condition.generateCode(currentScope, codeStream, false);
} else {
this.condition.generateOptimizedBoolean(
@@ -209,10 +206,7 @@
}
} else if (hasElsePart) {
// generate boolean condition only if needed
- if (((this.bits & ASTNode.IsThenStatementUnreachable) != 0) ||
- (cst != Constant.NotAConstant && cst.booleanValue() == false)) {
- // No need to generate if condition statement when we know that only the else action
- // will be executed
+ if (cst != Constant.NotAConstant && cst.booleanValue() == false) {
this.condition.generateCode(currentScope, codeStream, false);
} else {
this.condition.generateOptimizedBoolean(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index c6c3bde..2ea7500 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -78,7 +78,7 @@
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
// record variable initialization if any
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.IsLocalDeclarationReachable; // only set if actually reached
}
if (this.binding != null && this.type.resolvedType instanceof TypeVariableBinding) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index fcc3378..84e44b9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -390,7 +390,7 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo){
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
// if method from parameterized type got found, use the original method at codegen time
MethodBinding codegenBinding = this.binding.original();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 761df2b..bba3939 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -164,7 +164,7 @@
// check for missing returning path
TypeBinding returnTypeBinding = this.binding.returnType;
if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.NeedFreeReturn;
}
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
index c041fee..4b3fca4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -59,7 +59,7 @@
if (isLeftOptimizedTrue){
if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
currentScope.problemReporter().fakeReachable(this.right);
- rightInfo.setReachMode(FlowInfo.UNREACHABLE);
+ rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
}
rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 48bea2c..18a692b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -266,7 +266,7 @@
* exact need.
*/
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
// perform some extra emulation work in case there is some and we are inside a local type only
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 9b17a89..368c64a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -929,7 +929,7 @@
* index is <0 to denote write access emulation
*/
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
if (fieldBinding.constant() != Constant.NotAConstant)
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 3974bcf..392466e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -862,7 +862,7 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
//If inlinable field, forget the access emulation, the code gen will directly target it
if (this.constant != Constant.NotAConstant)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 1d36009..fdbd5a0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -83,7 +83,7 @@
// Report an error if necessary (if even more unreachable than previously reported
// complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) {
- if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
+ if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.bits &= ~ASTNode.IsReachable;
//{ObjectTeams: ignore generated "return _OT$result" (generateCode will also ignore this statement):
boolean shouldReport = true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
index 1ce89ee..b2c6dfd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -64,7 +64,7 @@
currentScope.methodScope().recordInitializationStates(flowInfo);
// optimizing code gen
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.bits |= ASTNode.BlockExit;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 365cc44..aad2e5f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -116,7 +116,7 @@
tryInfo = flowInfo;
} else {
tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy());
- if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+ if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
this.bits |= ASTNode.IsTryBlockExiting;
}
@@ -165,7 +165,7 @@
ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
*/
if (this.tryBlock.statements == null) {
- catchInfo.setReachMode(FlowInfo.UNREACHABLE);
+ catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
catchInfo =
this.catchBlocks[i].analyseCode(
@@ -174,7 +174,7 @@
catchInfo);
this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
this.catchExits[i] =
- (catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
+ (catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
}
}
@@ -225,7 +225,7 @@
tryInfo = flowInfo;
} else {
tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy());
- if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+ if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
this.bits |= ASTNode.IsTryBlockExiting;
}
@@ -274,7 +274,7 @@
ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
*/
if (this.tryBlock.statements == null) {
- catchInfo.setReachMode(FlowInfo.UNREACHABLE);
+ catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
catchInfo =
this.catchBlocks[i].analyseCode(
@@ -283,7 +283,7 @@
catchInfo);
this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
this.catchExits[i] =
- (catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
+ (catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 79408af..78d4769 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -524,7 +524,7 @@
if (this.ignoreFurtherInvestigation)
return flowInfo;
try {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.IsReachable;
LocalTypeBinding localType = (LocalTypeBinding) this.binding;
//{ObjectTeams: constantPoolName is set in advance for copy-inherited local types:
@@ -565,7 +565,7 @@
if (this.ignoreFurtherInvestigation)
return;
try {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.bits |= ASTNode.IsReachable;
LocalTypeBinding localType = (LocalTypeBinding) this.binding;
localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
@@ -1174,7 +1174,7 @@
for (int i = 0, count = this.fields.length; i < count; i++) {
FieldDeclaration field = this.fields[i];
if (field.isStatic()) {
- if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+ if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
field.bits &= ~ASTNode.IsReachable;
/*if (field.isField()){
@@ -1187,10 +1187,10 @@
// branch, since the previous initializer already got the blame.
if (staticFieldInfo == FlowInfo.DEAD_END) {
this.staticInitializerScope.problemReporter().initializerMustCompleteNormally(field);
- staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE);
+ staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
} else {
- if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+ if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
field.bits &= ~ASTNode.IsReachable;
/*if (field.isField()){
@@ -1203,7 +1203,7 @@
// branch, since the previous initializer already got the blame.
if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
this.initializerScope.problemReporter().initializerMustCompleteNormally(field);
- nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE);
+ nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
}
}
@@ -1331,7 +1331,7 @@
* 15.9.2
*/
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
MethodScope methodScope = currentScope.methodScope();
@@ -1382,7 +1382,7 @@
* Local member cannot be static.
*/
public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
nestedType.addSyntheticArgumentAndField(this.binding.enclosingType());
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
index 144e64e..c51042e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -82,7 +82,7 @@
} else {
FlowInfo mergedInfo = flowInfo.copy().addInitializationsFrom(condInfo.initsWhenFalse());
if (isConditionOptimizedTrue){
- mergedInfo.setReachMode(FlowInfo.UNREACHABLE);
+ mergedInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
this.mergedInitStateIndex =
currentScope.methodScope().recordInitializationStates(mergedInfo);
@@ -104,7 +104,7 @@
} else {
actionInfo = condInfo.initsWhenTrue().copy();
if (isConditionOptimizedFalse){
- actionInfo.setReachMode(FlowInfo.UNREACHABLE);
+ actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
}
}
@@ -120,11 +120,10 @@
// code generation can be optimized when no need to continue in the loop
exitBranch = flowInfo.copy();
// need to start over from flowInfo so as to get null inits
-
- if ((actionInfo.tagBits &
- loopingContext.initsOnContinue.tagBits &
- FlowInfo.UNREACHABLE) != 0) {
- this.continueLabel = null;
+ int combinedTagBits = actionInfo.tagBits & loopingContext.initsOnContinue.tagBits;
+ if ((combinedTagBits & FlowInfo.UNREACHABLE) != 0) {
+ if ((combinedTagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+ this.continueLabel = null;
exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
} else {
condLoopContext.complainOnDeferredFinalChecks(currentScope,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index c6c3348..c137b42 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -195,7 +195,7 @@
this.tagBits &= ~UNREACHABLE;
}
else {
- this.tagBits |= UNREACHABLE;
+ this.tagBits |= reachMode;
}
this.initsWhenTrue.setReachMode(reachMode);
this.initsWhenFalse.setReachMode(reachMode);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index e82b26c..c6b591e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -231,8 +231,8 @@
}
public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
- if ((this.initsOnReturn.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+ if ((this.initsOnReturn.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.initsOnReturn = this.initsOnReturn.mergedWith(flowInfo);
}
else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
index 37bf18f..0590583 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -229,14 +229,14 @@
scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
return;
@@ -252,7 +252,7 @@
scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
@@ -264,7 +264,7 @@
scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
@@ -314,14 +314,14 @@
scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
return;
@@ -342,7 +342,7 @@
scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
@@ -354,7 +354,7 @@
scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 369d24e..2ce915a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -530,7 +530,7 @@
}
public void recordSettingFinal(VariableBinding variable, Reference finalReference, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
// for initialization inside looping statement that effectively loops
FlowContext context = this;
while (context != null) {
@@ -578,14 +578,14 @@
scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
return;
@@ -609,7 +609,7 @@
scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
@@ -621,7 +621,7 @@
scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index bcf1b83..4cd7135 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -36,9 +36,24 @@
public int tagBits; // REACHABLE by default
public final static int REACHABLE = 0;
- public final static int UNREACHABLE = 1;
- public final static int NULL_FLAG_MASK = 2;
-
+ /* unreachable code
+ * eg. while (true);
+ * i++; --> unreachable code
+ */
+ public final static int UNREACHABLE_OR_DEAD = 1;
+ /* unreachable code as inferred by null analysis
+ * eg. str = null;
+ * if (str != null) {
+ * // dead code
+ * }
+ */
+ public final static int UNREACHABLE_BY_NULLANALYSIS = 2;
+ /*
+ * code unreachable in any fashion
+ */
+ public final static int UNREACHABLE = UNREACHABLE_OR_DEAD | UNREACHABLE_BY_NULLANALYSIS;
+ public final static int NULL_FLAG_MASK = 4;
+
public final static int UNKNOWN = 1;
public final static int NULL = 2;
public final static int NON_NULL = 4;
@@ -369,7 +384,7 @@
UnconditionalFlowInfo mergedInfo;
if (isOptimizedTrue){
if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
- mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE).
+ mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
unconditionalInits();
}
else {
@@ -381,7 +396,7 @@
}
else if (isOptimizedFalse) {
if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
- mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE).
+ mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
unconditionalInits();
}
else {
@@ -408,7 +423,7 @@
UnconditionalFlowInfo mergedInfo;
if (isOptimizedTrue){
if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
- mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE).
+ mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
unconditionalInits();
}
else {
@@ -420,7 +435,7 @@
}
else if (isOptimizedFalse) {
if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
- mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE).
+ mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
unconditionalInits();
}
else {
@@ -470,10 +485,9 @@
}
/**
- * Return REACHABLE if this flow info is reachable, UNREACHABLE
- * else.
- * @return REACHABLE if this flow info is reachable, UNREACHABLE
- * else
+ * Find out the reachability mode of this flowInfo.
+ * @return REACHABLE if this flow info is reachable, otherwise
+ * either UNREACHABLE_OR_DEAD or UNREACHABLE_BY_NULLANALYSIS.
*/
public int reachMode() {
return this.tagBits & UNREACHABLE;
@@ -490,7 +504,8 @@
/**
* Set this flow info reach mode and return this.
- * @param reachMode one of {@link #REACHABLE REACHABLE} or {@link #UNREACHABLE UNREACHABLE}
+ * @param reachMode one of {@link #REACHABLE REACHABLE}, {@link #UNREACHABLE_OR_DEAD UNREACHABLE_OR_DEAD},
+ * {@link #UNREACHABLE_BY_NULLANALYSIS UNREACHABLE_BY_NULLANALYSIS} or {@link #UNREACHABLE UNREACHABLE}
* @return this, with the reach mode set to reachMode
*/
abstract public FlowInfo setReachMode(int reachMode);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
index 4ffc764..4daa2c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -43,7 +43,7 @@
}
public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
if (this.initsOnReturn == FlowInfo.DEAD_END) {
this.initsOnReturn = (UnconditionalFlowInfo) flowInfo.copy();
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
index 6606cbe..9355779 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - contribution for Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
@@ -384,42 +385,42 @@
}
public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
- if ((this.initsOnContinue.tagBits & FlowInfo.UNREACHABLE) == 0) {
- this.initsOnContinue = this.initsOnContinue.
- mergedWith(flowInfo.unconditionalInitsWithoutSideEffect());
- }
- else {
- this.initsOnContinue = flowInfo.unconditionalCopy();
- }
- FlowContext inner = innerFlowContext;
- while (inner != this && !(inner instanceof LoopingFlowContext)) {
- inner = inner.parent;
- }
- if (inner == this) {
- this.upstreamNullFlowInfo.
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+ if ((this.initsOnContinue.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+ this.initsOnContinue = this.initsOnContinue.
+ mergedWith(flowInfo.unconditionalInitsWithoutSideEffect());
+ }
+ else {
+ this.initsOnContinue = flowInfo.unconditionalCopy();
+ }
+ FlowContext inner = innerFlowContext;
+ while (inner != this && !(inner instanceof LoopingFlowContext)) {
+ inner = inner.parent;
+ }
+ if (inner == this) {
+ this.upstreamNullFlowInfo.
addPotentialNullInfoFrom(
- flowInfo.unconditionalInitsWithoutSideEffect());
- }
- else {
- int length = 0;
- if (this.innerFlowContexts == null) {
- this.innerFlowContexts = new LoopingFlowContext[5];
- this.innerFlowInfos = new UnconditionalFlowInfo[5];
+ flowInfo.unconditionalInitsWithoutSideEffect());
}
- else if (this.innerFlowContextsCount ==
- (length = this.innerFlowContexts.length) - 1) {
- System.arraycopy(this.innerFlowContexts, 0,
- (this.innerFlowContexts = new LoopingFlowContext[length + 5]),
- 0, length);
- System.arraycopy(this.innerFlowInfos, 0,
- (this.innerFlowInfos= new UnconditionalFlowInfo[length + 5]),
- 0, length);
+ else {
+ int length = 0;
+ if (this.innerFlowContexts == null) {
+ this.innerFlowContexts = new LoopingFlowContext[5];
+ this.innerFlowInfos = new UnconditionalFlowInfo[5];
+ }
+ else if (this.innerFlowContextsCount ==
+ (length = this.innerFlowContexts.length) - 1) {
+ System.arraycopy(this.innerFlowContexts, 0,
+ (this.innerFlowContexts = new LoopingFlowContext[length + 5]),
+ 0, length);
+ System.arraycopy(this.innerFlowInfos, 0,
+ (this.innerFlowInfos= new UnconditionalFlowInfo[length + 5]),
+ 0, length);
+ }
+ this.innerFlowContexts[this.innerFlowContextsCount] = (LoopingFlowContext) inner;
+ this.innerFlowInfos[this.innerFlowContextsCount++] =
+ flowInfo.unconditionalInitsWithoutSideEffect();
}
- this.innerFlowContexts[this.innerFlowContextsCount] = (LoopingFlowContext) inner;
- this.innerFlowInfos[this.innerFlowContextsCount++] =
- flowInfo.unconditionalInitsWithoutSideEffect();
- }
}
}
@@ -493,14 +494,14 @@
scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
} else if (flowInfo.isDefinitelyNull(local)) {
@@ -509,14 +510,14 @@
scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {
@@ -525,11 +526,18 @@
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
recordNullReference(local, reference, checkType);
}
- } else if (! flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
- if (flowInfo.isPotentiallyNonNull(local)) {
- recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK);
- } else {
- if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+ } else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
+ return; // no reason to complain, since there is definitely some uncertainty making the comparison relevant.
+ } else {
+ if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+ // note: pot non-null & pot null is already captured by cannotBeDefinitelyNullOrNonNull()
+ if (flowInfo.isPotentiallyNonNull(local)) {
+ // knowing 'local' can be non-null, we're only interested in seeing whether it can *only* be non-null
+ recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK);
+ } else if (flowInfo.isPotentiallyNull(local)) {
+ // knowing 'local' can be null, we're only interested in seeing whether it can *only* be null
+ recordNullReference(local, reference, CAN_ONLY_NULL | checkType & CONTEXT_MASK);
+ } else {
recordNullReference(local, reference, checkType);
}
}
@@ -554,7 +562,7 @@
scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
@@ -566,7 +574,7 @@
scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
- flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+ flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
index f0772c0..c17fa4e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -42,7 +42,7 @@
}
public void recordBreakFrom(FlowInfo flowInfo) {
- if ((this.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) == 0) {
+ if ((this.initsOnBreak.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
this.initsOnBreak = this.initsOnBreak.mergedWith(flowInfo.unconditionalInits());
}
else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index cf23292..0de5fc4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -742,7 +742,7 @@
final public boolean isDefinitelyAssigned(FieldBinding field) {
// Mirrored in CodeStream.isDefinitelyAssigned(..)
// do not want to complain in unreachable code
- if ((this.tagBits & UNREACHABLE) != 0) {
+ if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
return true;
}
//{ObjectTeams: if it is copied don't require definite assignment again
@@ -754,7 +754,7 @@
final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
// do not want to complain in unreachable code if local declared in reachable code
- if ((this.tagBits & UNREACHABLE) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
+ if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
return true;
}
return isDefinitelyAssigned(local.id + this.maxFieldCount);
@@ -1551,7 +1551,7 @@
}
public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
- if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) {
+ if ((otherInits.tagBits & UNREACHABLE_OR_DEAD) != 0 && this != DEAD_END) {
if (COVERAGE_TEST_FLAG) {
if(CoverageTestId == 28) {
throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$
@@ -1560,7 +1560,7 @@
combineNullStatusChangeInAssertInfo(otherInits);
return this;
}
- if ((this.tagBits & UNREACHABLE) != 0) {
+ if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
if (COVERAGE_TEST_FLAG) {
if(CoverageTestId == 29) {
throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$
@@ -1585,7 +1585,17 @@
na1, na2, na3, na4,
nb1, nb2, nb3, nb4,
b1, b2, b3, b4;
- if (thisHadNulls) {
+ if ((otherInits.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) {
+ otherHasNulls = false; // skip merging, otherInits is unreachable by null analysis
+ } else if ((this.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) { // directly copy if this is unreachable by null analysis
+ this.nullBit1 = otherInits.nullBit1;
+ this.nullBit2 = otherInits.nullBit2;
+ this.nullBit3 = otherInits.nullBit3;
+ this.nullBit4 = otherInits.nullBit4;
+ thisHadNulls = false;
+ thisHasNulls = otherHasNulls;
+ this.tagBits = otherInits.tagBits;
+ } else if (thisHadNulls) {
if (otherHasNulls) {
this.nullBit1 = (a2 = this.nullBit2) & (a3 = this.nullBit3)
& (a4 = this.nullBit4) & (b1 = otherInits.nullBit1)
@@ -1880,6 +1890,8 @@
}
if (reachMode == REACHABLE ) {
this.tagBits &= ~UNREACHABLE;
+ } else if (reachMode == UNREACHABLE_BY_NULLANALYSIS ) {
+ this.tagBits |= UNREACHABLE_BY_NULLANALYSIS; // do not interfere with definite assignment analysis
} else {
if ((this.tagBits & UNREACHABLE) == 0) {
// reset optional inits when becoming unreachable
@@ -1892,7 +1904,7 @@
}
}
}
- this.tagBits |= UNREACHABLE;
+ this.tagBits |= reachMode;
}
return this;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index a5d01bf..becddb0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -508,7 +508,7 @@
}
public final int recordInitializationStates(FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return -1;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return -1;
UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInitsWithoutSideEffect();
long[] extraInits = unconditionalFlowInfo.extra == null ?
null : unconditionalFlowInfo.extra[0];
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
index 6f0ad72..cc91b87 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -17,30 +17,31 @@
* <p>
* <pre>
* Expression:
- * Name
- * NumberLiteral
- * CharacterLiteral
- * NullLiteral
- * BooleanLiteral
- * StringLiteral
- * TypeLiteral
- * ThisExpression
- * SuperFieldAccess
- * FieldAccess
- * Assignment
- * ParenthesizedExpression
- * ClassInstanceCreation
- * ArrayCreation
- * ArrayInitializer
- * MethodInvocation
- * SuperMethodInvocation
- * ArrayAccess
- * InfixExpression
- * InstanceofExpression
- * ConditionalExpression
- * PostfixExpression
- * PrefixExpression
- * CastExpression
+ * Annotation,
+ * ArrayAccess,
+ * ArrayCreation,
+ * ArrayInitializer,
+ * Assignment,
+ * BooleanLiteral,
+ * CastExpression,
+ * CharacterLiteral,
+ * ClassInstanceCreation,
+ * ConditionalExpression,
+ * FieldAccess,
+ * InfixExpression,
+ * InstanceofExpression,
+ * MethodInvocation,
+ * Name,
+ * NullLiteral,
+ * NumberLiteral,
+ * ParenthesizedExpression,
+ * PostfixExpression,
+ * PrefixExpression,
+ * StringLiteral,
+ * SuperFieldAccess,
+ * SuperMethodInvocation,
+ * ThisExpression,
+ * TypeLiteral,
* VariableDeclarationExpression
* </pre>
* </p>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
index 84d426b..36d2268 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,51 +23,53 @@
* For JLS2:
* <pre>
* Statement:
- * Block
- * IfStatement
- * ForStatement
- * WhileStatement
- * DoStatement
- * TryStatement
- * SwitchStatement
- * SynchronizedStatement
- * ReturnStatement
- * ThrowStatement
- * BreakStatement
- * ContinueStatement
- * EmptyStatement
- * ExpressionStatement
- * LabeledStatement
- * AssertStatement
- * VariableDeclarationStatement
- * TypeDeclarationStatement
- * ConstructorInvocation
- * SuperConstructorInvocation
+ * AssertStatement,
+ * Block,
+ * BreakStatement,
+ * ConstructorInvocation,
+ * ContinueStatement,
+ * DoStatement,
+ * EmptyStatement,
+ * ExpressionStatement,
+ * ForStatement,
+ * IfStatement,
+ * LabeledStatement,
+ * ReturnStatement,
+ * SuperConstructorInvocation,
+ * SwitchCase,
+ * SwitchStatement,
+ * SynchronizedStatement,
+ * ThrowStatement,
+ * TryStatement,
+ * TypeDeclarationStatement,
+ * VariableDeclarationStatement,
+ * WhileStatement
* </pre>
* For JLS3, an enhanced for node type was added:
* <pre>
* Statement:
- * Block
- * IfStatement
- * ForStatement
- * EnhancedForStatement
+ * AssertStatement,
+ * Block,
+ * BreakStatement,
+ * ConstructorInvocation,
+ * ContinueStatement,
+ * DoStatement,
+ * EmptyStatement,
+ * EnhancedForStatement,
+ * ExpressionStatement,
+ * ForStatement,
+ * IfStatement,
+ * LabeledStatement,
+ * ReturnStatement,
+ * SuperConstructorInvocation,
+ * SwitchCase,
+ * SwitchStatement,
+ * SynchronizedStatement,
+ * ThrowStatement,
+ * TryStatement,
+ * TypeDeclarationStatement,
+ * VariableDeclarationStatement,
* WhileStatement
- * DoStatement
- * TryStatement
- * SwitchStatement
- * SynchronizedStatement
- * ReturnStatement
- * ThrowStatement
- * BreakStatement
- * ContinueStatement
- * EmptyStatement
- * ExpressionStatement
- * LabeledStatement
- * AssertStatement
- * VariableDeclarationStatement
- * TypeDeclarationStatement
- * ConstructorInvocation
- * SuperConstructorInvocation
* </pre>
* </p>
*
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
index 71d12e0..4cd8083 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -278,7 +278,7 @@
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess){
// The private access will be managed through the code generation
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
}
public TypeBinding resolveType(BlockScope scope) {
// Answer the signature type of the field.
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index feef879..439f8ed 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -172,8 +172,8 @@
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
- // if method from parameterized type got found, use the original method at codegen time
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+ // if method from parameterized type got found, use the original method at codegen time
MethodBinding codegenBinding = this.binding.original();
if (codegenBinding != this.binding) {
// extra cast needed if method return type was type variable
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
index 151a215..ea2877b 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -576,7 +576,7 @@
return;
}
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
//If inlinable field, forget the access emulation, the code gen will directly target it
if (this.constant != Constant.NotAConstant)
return;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
index 1ae3ff1..64935a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -49,7 +49,9 @@
* Java project elements need to be opened before they can be navigated or manipulated.
* The children of a Java project are the package fragment roots that are
* defined by the classpath and contained in this project (in other words, it
- * does not include package fragment roots for other projects).
+ * does not include package fragment roots for other projects). The children
+ * (i.e. the package fragment roots) appear in the order they are defined by
+ * the classpath.
* </p>
* <p>
* An instance of one of these handles can be created via
@@ -518,7 +520,8 @@
* Returns all of the package fragment roots contained in this
* project, identified on this project's resolved classpath. The result
* does not include package fragment roots in other projects referenced
- * on this project's classpath.
+ * on this project's classpath. The package fragment roots appear in the
+ * order they are defined by the classpath.
*
* <p>NOTE: This is equivalent to <code>getChildren()</code>.
*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 003f397..9d1aaf5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -282,12 +282,71 @@
if (parent != null && parent.isOpen()) {
try {
OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
- info.addChild(child);
- } catch (JavaModelException e) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006
+ // Insert the package fragment roots in the same order as the classpath order.
+ if (child instanceof IPackageFragmentRoot)
+ addPackageFragmentRoot(info, (IPackageFragmentRoot) child);
+ else
+ info.addChild(child);
+ } catch (JavaModelException e) {
// do nothing - we already checked if open
}
}
}
+
+ private void addPackageFragmentRoot(OpenableElementInfo parent, IPackageFragmentRoot child)
+ throws JavaModelException {
+
+ IJavaElement[] roots = parent.getChildren();
+ if (roots.length > 0) {
+ IClasspathEntry[] resolvedClasspath = ((JavaProject) child.getJavaProject()).getResolvedClasspath();
+ IPath currentEntryPath = child.getResolvedClasspathEntry().getPath();
+ int indexToInsert = -1;
+ int lastComparedIndex = -1;
+ int i = 0, j = 0;
+ for (; i < roots.length && j < resolvedClasspath.length;) {
+
+ IClasspathEntry classpathEntry = resolvedClasspath[j];
+ if (lastComparedIndex != j && currentEntryPath.equals(classpathEntry.getPath())) {
+ indexToInsert = i;
+ break;
+ }
+ lastComparedIndex = j;
+
+ IClasspathEntry rootEntry = ((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry();
+ if (rootEntry.getPath().equals(classpathEntry.getPath()))
+ i++;
+ else
+ j++;
+ }
+
+ for (; i < roots.length; i++) {
+ // If the new root is already among the children, no need to proceed further. Just return.
+ if (roots[i].equals(child)) {
+ return;
+ }
+ // If we start seeing root's classpath entry different from the child's entry, then the child can't
+ // be present further down the roots array.
+ if (!((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry().getPath()
+ .equals(currentEntryPath))
+ break;
+ }
+
+ if (indexToInsert >= 0) {
+ int newSize = roots.length + 1;
+ IPackageFragmentRoot[] newChildren = new IPackageFragmentRoot[newSize];
+
+ if (indexToInsert > 0)
+ System.arraycopy(roots, 0, newChildren, 0, indexToInsert);
+
+ newChildren[indexToInsert] = child;
+ System.arraycopy(roots, indexToInsert, newChildren, indexToInsert + 1, (newSize - indexToInsert - 1));
+ parent.setChildren(newChildren);
+ return;
+ }
+ }
+ parent.addChild(child);
+ }
/*
* Process the given delta and look for projects being added, opened, closed or
* with a java nature being added or removed.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index ae3da8c..56d449d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -2631,6 +2631,7 @@
JavaModelManager manager = JavaModelManager.getJavaModelManager();
ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
ResolvedClasspath result = new ResolvedClasspath();
+ Map knownDrives = new HashMap();
Map referencedEntriesMap = new HashMap();
List rawLibrariesPath = new ArrayList();
@@ -2691,11 +2692,11 @@
if (!rawLibrariesPath.contains(extraEntries[j].getPath())) {
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305037
// referenced entries for variable entries could also be persisted with extra attributes, so addAsChainedEntry = true
- addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true);
+ addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
}
}
}
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
}
break;
@@ -2738,12 +2739,12 @@
ClasspathEntry[] extraEntries = cEntry.resolvedChainedLibraries();
for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
- addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+ addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
}
}
}
}
- addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+ addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
}
break;
@@ -2756,15 +2757,15 @@
ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
- addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true);
+ addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
}
}
}
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
break;
default :
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
break;
}
}
@@ -2775,7 +2776,7 @@
private void addToResult(IClasspathEntry rawEntry, IClasspathEntry resolvedEntry, ResolvedClasspath result,
LinkedHashSet resolvedEntries, ExternalFoldersManager externalFoldersManager,
- Map oldChainedEntriesMap, boolean addAsChainedEntry) {
+ Map oldChainedEntriesMap, boolean addAsChainedEntry, Map knownDrives) {
IPath resolvedPath;
// If it's already been resolved, do not add to resolvedEntries
@@ -2799,7 +2800,7 @@
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=336046
// The source attachment path could be external too and in which case, must be added.
IPath sourcePath = resolvedEntry.getSourceAttachmentPath();
- if (sourcePath != null && ExternalFoldersManager.isExternalFolderPath(sourcePath)) {
+ if (sourcePath != null && driveExists(sourcePath, knownDrives) && ExternalFoldersManager.isExternalFolderPath(sourcePath)) {
externalFoldersManager.addFolder(sourcePath, true);
}
}
@@ -2820,6 +2821,26 @@
}
/*
+ * File#exists() takes lot of time for an unmapped drive. Hence, cache the info.
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649
+ */
+ private boolean driveExists(IPath sourcePath, Map knownDrives) {
+ String drive = sourcePath.getDevice();
+ if (drive == null) return true;
+ Boolean good = (Boolean)knownDrives.get(drive);
+ if (good == null) {
+ if (new File(drive).exists()) {
+ knownDrives.put(drive, Boolean.TRUE);
+ return true;
+ } else {
+ knownDrives.put(drive, Boolean.FALSE);
+ return false;
+ }
+ }
+ return good.booleanValue();
+ }
+
+ /*
* Resolve the given perProjectInfo's raw classpath and store the resolved classpath in the perProjectInfo.
*/
public void resolveClasspath(PerProjectInfo perProjectInfo, boolean usePreviousSession, boolean addClasspathChange) throws JavaModelException {