Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 298139
Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java (-5 / +96 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 11-21 Link Here
11
package org.eclipse.jdt.internal.compiler.ast;
11
package org.eclipse.jdt.internal.compiler.ast;
12
12
13
import org.eclipse.jdt.internal.compiler.ASTVisitor;
13
import org.eclipse.jdt.internal.compiler.ASTVisitor;
14
import org.eclipse.jdt.internal.compiler.impl.*;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
14
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.codegen.*;
15
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
17
import org.eclipse.jdt.internal.compiler.flow.*;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
18
import org.eclipse.jdt.internal.compiler.lookup.*;
17
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
18
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
19
import org.eclipse.jdt.internal.compiler.impl.Constant;
20
import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
21
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
22
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
23
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
24
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
19
25
20
public class BinaryExpression extends OperatorExpression {
26
public class BinaryExpression extends OperatorExpression {
21
27
Lines 64-69 Link Here
64
							this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
70
							this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
65
						.unconditionalInits();
71
						.unconditionalInits();
66
	} else {
72
	} else {
73
		if ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OR) {
74
			Constant cst = this.left.optimizedBooleanConstant();
75
			if (cst instanceof BooleanConstant) {
76
				boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
77
				if (isLeftOptimizedFalse) {
78
					// FALSE | anything
79
					FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
80
					mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo);
81
					return mergedInfo;
82
				}
83
			}
84
			this.left.checkNPE(currentScope, flowContext, flowInfo);
85
			FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo);
86
			this.right.checkNPE(currentScope, flowContext, leftInfo);
87
			FlowInfo rightInfo = leftInfo.unconditionalCopy();
88
			FlowInfo rightInfoWhenExpressionFalse = leftInfo.initsWhenFalse().unconditionalCopy();
89
			rightInfoWhenExpressionFalse = this.right.analyseCode(currentScope, flowContext, rightInfoWhenExpressionFalse);
90
			rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
91
			
92
			FlowInfo leftInfoWhenTrue = leftInfo.initsWhenTrue().unconditionalCopy();
93
			FlowInfo leftInfoWhenFalse = leftInfo.initsWhenFalse().unconditionalCopy();
94
			
95
			//following steps are needed to ensure the initializations of rightInfo are not lost while merging
96
			leftInfoWhenTrue.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect());
97
			leftInfoWhenFalse.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect());
98
			/* Merging as follows:
99
			 * For the whole expression to be true, conditions:
100
			 * 1. left is false, right is true
101
			 * 2. left is true, right is false
102
			 * 3. left is true, right is true
103
			 * For the whole expression to be false, condition:
104
			 * left is false, right is false.
105
			 */
106
			FlowInfo mergedInfo = FlowInfo.conditional(
107
					leftInfoWhenTrue.unconditionalInits().mergedWith(
108
						rightInfo.initsWhenTrue().unconditionalInits()).mergedWith(
109
								leftInfoWhenTrue.unconditionalInits().mergedWith(
110
										rightInfo.initsWhenFalse().unconditionalInits())).mergedWith(
111
												leftInfoWhenFalse.unconditionalInits().mergedWith(
112
														rightInfo.initsWhenTrue().unconditionalInits())),
113
					rightInfoWhenExpressionFalse.initsWhenFalse());									
114
			return mergedInfo;
115
		} else if ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == AND) {
116
			Constant cst = this.left.optimizedBooleanConstant();
117
			if (cst instanceof BooleanConstant) {
118
				 boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
119
				 if (isLeftOptimizedTrue) {
120
					 // TRUE & anything
121
					 FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo)
122
							.unconditionalInits();
123
					 mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo);
124
					 return mergedInfo;
125
				 }
126
			}
127
			this.left.checkNPE(currentScope, flowContext, flowInfo);
128
			FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo);
129
			this.right.checkNPE(currentScope, flowContext, leftInfo);
130
			FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalCopy();
131
			rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
132
			FlowInfo leftInfoWhenFalse = leftInfo.initsWhenFalse();
133
			// The following step is to make sure that while merging and creating mergedInfo
134
			// we don't miss out potentially null candidates in rightInfo
135
			// This is because if a variable is definitely null in rightInfo.initsWhenFalse, and its nullness
136
			// is not known in leftInfo.initsWhenFalse, the merging will leave it out while taking
137
			// intersection of definitely null variables. So we just need to make sure that leftInfo.initsWhenFalse
138
			// also knows about it.
139
			leftInfoWhenFalse.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect());
140
			/* Merging as follows:
141
			 * For the whole expression to be true, conditions:
142
			 * left is false, right is false.
143
			 * For the whole expression to be false, condition:
144
			 * 1. left is false, right is true
145
			 * 2. left is true, right is false
146
			 * 3. left is false, right is false
147
			 */
148
			FlowInfo mergedInfo = FlowInfo.conditional(
149
				rightInfo.safeInitsWhenTrue(),
150
					leftInfo.initsWhenTrue().unconditionalInits().mergedWith(
151
							rightInfo.initsWhenFalse().unconditionalInits()).mergedWith(
152
									leftInfoWhenFalse.unconditionalInits().mergedWith(
153
										rightInfo.initsWhenFalse().unconditionalInits())).mergedWith(
154
												leftInfoWhenFalse.unconditionalInits().mergedWith(
155
														rightInfo.initsWhenTrue().unconditionalInits())));
156
			return mergedInfo;
157
		} 
67
		this.left.checkNPE(currentScope, flowContext, flowInfo);
158
		this.left.checkNPE(currentScope, flowContext, flowInfo);
68
		flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
159
		flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
69
		this.right.checkNPE(currentScope, flowContext, flowInfo);
160
		this.right.checkNPE(currentScope, flowContext, flowInfo);

Return to bug 298139