diff options
author | Sasikanth Bharadwaj | 2016-11-25 09:48:43 +0000 |
---|---|---|
committer | Sasikanth Bharadwaj | 2017-01-05 09:50:20 +0000 |
commit | 0bb7ec7ec0cbecabdaa516a555e1f91baa204946 (patch) | |
tree | 9f0de24c32629ef7f5f6cf830d281c713c719e4d | |
parent | 78d592611dbb845af82c1ddde716da6e242698d3 (diff) | |
download | eclipse.jdt.core-R4_4_1_maintenance.tar.gz eclipse.jdt.core-R4_4_1_maintenance.tar.xz eclipse.jdt.core-R4_4_1_maintenance.zip |
Fixed bug 499809: [null][1.8] VerifyError when Null Analysis is onR4_4_1_maintenance
Change-Id: I6fee92111d345d6581679479a27a134f875c5852
4 files changed, 105 insertions, 6 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java index e521892a46..f77f4a5d76 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2016 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 @@ -2700,6 +2700,50 @@ public void testBug415997c() { }, "test"); } +public void testBug499809() { + this.runConformTest( + new String[] { + "Foo.java", + "public class Foo {\n" + + " static void foo( ) {\n" + + " String _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, a, b,\n" + + " c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, s0, s1, s2, s3, s4, s5, s6, s7;\n" + + " Object ob = new Object();\n" + + " int int1 = 0, int2 = 2, int3, int4;\n" + + " if (ob != null) {\n" + + " int4 = 1;\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(\"Done\");\n" + + " }\n" + + "}\n" + }, + "Done"); +} +public void testBug499809a() { + this.runConformTest( + new String[] { + "Foo.java", + "public class Foo {\n" + + " static void foo( ) {\n" + + " String _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, a, b,\n" + + " c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, s0, s1, s2, s3, s4, s5, s6, s7;\n" + + " Object ob = new Object();\n" + + " int int1 = 0, int2 = 2, int3, int4;\n" + + " if (ob == null) {\n" + + " int1 = 1;\n" + + " } else {\n" + + " int4 = 1;\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(\"Done\");\n" + + " }\n" + + "}\n" + }, + "Done"); +} public static Class testClass() { return FlowAnalysisTest.class; } 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 288fb8f4dc..2d5fd51673 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, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -214,7 +214,9 @@ public FlowInfo setReachMode(int reachMode) { public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { return unconditionalInits().mergedWith(otherInits); } - +public UnconditionalFlowInfo mergeDefiniteInitsWith(UnconditionalFlowInfo otherInits) { + return unconditionalInits().mergeDefiniteInitsWith(otherInits); +} public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() { return unconditionalInitsWithoutSideEffect(). nullInfoLessUnconditionalCopy(); 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 838843cf75..018886f059 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 @@ -533,7 +533,8 @@ public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse( unconditionalInits(); // if a variable is only initialized in one branch and not initialized in the other, // then we need to cast a doubt on its initialization in the merged info - mergedInfo.definiteInits &= initsWhenFalse.unconditionalCopy().definiteInits; + mergedInfo.mergeDefiniteInitsWith(initsWhenFalse.unconditionalCopy()); + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsElseStatementUnreachable could be due to null analysis if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenFalse.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) { mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD; @@ -553,7 +554,7 @@ public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse( unconditionalInits(); // if a variable is only initialized in one branch and not initialized in the other, // then we need to cast a doubt on its initialization in the merged info - mergedInfo.definiteInits &= initsWhenTrue.unconditionalCopy().definiteInits; + mergedInfo.mergeDefiniteInitsWith(initsWhenTrue.unconditionalCopy()); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsThenStatementUnreachable could be due to null analysis if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenTrue.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) { mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD; @@ -610,6 +611,8 @@ abstract public FlowInfo setReachMode(int reachMode); abstract public UnconditionalFlowInfo mergedWith( UnconditionalFlowInfo otherInits); +abstract public UnconditionalFlowInfo mergeDefiniteInitsWith(UnconditionalFlowInfo otherInits); + /** * Return a copy of this unconditional flow info, deprived from its null * info. {@link #DEAD_END DEAD_END} is returned unmodified. 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 394486e9bd..91ac1c22bd 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -2088,7 +2088,57 @@ public UnconditionalFlowInfo unconditionalInits() { public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() { return this; } +public UnconditionalFlowInfo mergeDefiniteInitsWith(UnconditionalFlowInfo otherInits) { + if ((otherInits.tagBits & UNREACHABLE_OR_DEAD) != 0 && this != DEAD_END) { + return this; + } + if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) { + return (UnconditionalFlowInfo) otherInits.copy(); // make sure otherInits won't be affected + } + // intersection of definitely assigned variables, + this.definiteInits &= otherInits.definiteInits; + if (this.extra != null) { + if (otherInits.extra != null) { + // both sides have extra storage + int i = 0, length, otherLength; + if ((length = this.extra[0].length) < (otherLength = otherInits.extra[0].length)) { + // current storage is shorter -> grow current + for (int j = 0; j < extraLength; j++) { + System.arraycopy(this.extra[j], 0, + (this.extra[j] = new long[otherLength]), 0, length); + } + for (; i < length; i++) { + this.extra[0][i] &= otherInits.extra[0][i]; + } + for (; i < otherLength; i++) { + this.extra[0][i] = otherInits.extra[0][i]; + } + } + else { + // current storage is longer + for (; i < otherLength; i++) { + this.extra[0][i] &= otherInits.extra[0][i]; + } + } + } else { + for (int i = 0; i < this.extra[0].length; i++) { + this.extra[0][i] = 0; + } + } + } + else if (otherInits.extra != null) { + // no storage here, but other has extra storage. + int otherLength = otherInits.extra[0].length; + this.extra = new long[extraLength][]; + for (int j = 0; j < extraLength; j++) { + this.extra[j] = new long[otherLength]; + } + System.arraycopy(otherInits.extra[0], 0, this.extra[0], 0, + otherLength); + } + return this; +} public void resetAssignmentInfo(LocalVariableBinding local) { resetAssignmentInfo(local.id + this.maxFieldCount); } |