diff options
author | Stephan Herrmann | 2012-08-25 18:40:16 +0000 |
---|---|---|
committer | Jayaprakash Arthanareeswaran | 2012-10-09 06:58:21 +0000 |
commit | 9f12877d36983b110529cd16673958f10cc774c5 (patch) | |
tree | 94e92f2f395597b74587626b89ccae3bea7fbe97 | |
parent | 7ad108ea3de2b7d68d2737f4428379110b97b811 (diff) | |
download | eclipse.jdt.core-9f12877d36983b110529cd16673958f10cc774c5.tar.gz eclipse.jdt.core-9f12877d36983b110529cd16673958f10cc774c5.tar.xz eclipse.jdt.core-9f12877d36983b110529cd16673958f10cc774c5.zip |
Bug 386181 - [compiler][null] wrong transition in
UnconditionalFlowInfo.mergedWith()
3 files changed, 74 insertions, 96 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java index 8f0a55ad96..ffa67b41e0 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java @@ -10,6 +10,7 @@ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for * bug 320170 * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" + * bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -850,7 +851,7 @@ public void test2500_addInitializationsFrom_for_definites() { // Note: coverage tests tend to fill the console with messages, and the // instrumented code is slower, so never release code with active // coverage tests. -private static int coveragePointsNb = 41; +private static int coveragePointsNb = 45; // PREMATURE reactivate coverage tests // Coverage by state transition tables methods. @@ -869,6 +870,11 @@ public void test2998_coverage() { test2060_addInitializationsFrom(); test2061_addPotentialInitializationsFrom(); test2062_mergedWith(); + testBug292478(); + testBug292478c(); + test0331_if_else_nested(); + testBug325755b(); + testBug292478g(); // coverage check int failuresNb = 0; for (int i = 1; i <= coveragePointsNb; i++) { @@ -890,6 +896,11 @@ public void test2998_coverage() { test2060_addInitializationsFrom(); test2061_addPotentialInitializationsFrom(); test2062_mergedWith(); + testBug292478(); + testBug292478c(); + test0331_if_else_nested(); + testBug325755b(); + testBug292478g(); } catch (AssertionFailedError e) { continue; diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java index 7162b30921..c1b13b189b 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" + * bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -1174,6 +1175,7 @@ public class NullReferenceImplTransformations { {0x00,0x10,0x10}, {0x00,0x14,0x14}, {0x00,0x18,0x18}, + {0x00,0x1C,0x1C}, {0x00,0x24,0x04}, {0x00,0x28,0x08}, {0x00,0x2C,0x08}, @@ -1187,6 +1189,7 @@ public class NullReferenceImplTransformations { {0x04,0x10,0x14}, {0x04,0x14,0x14}, {0x04,0x18,0x18}, + {0x04,0x1C,0x1C}, {0x04,0x24,0x04}, {0x04,0x28,0x0C}, {0x04,0x2C,0x0C}, @@ -1197,6 +1200,7 @@ public class NullReferenceImplTransformations { {0x08,0x10,0x18}, {0x08,0x14,0x18}, {0x08,0x18,0x18}, + {0x08,0x1C,0x1C}, {0x08,0x24,0x0C}, {0x08,0x28,0x08}, {0x08,0x2C,0x08}, @@ -1206,6 +1210,7 @@ public class NullReferenceImplTransformations { {0x0C,0x10,0x18}, {0x0C,0x14,0x18}, {0x0C,0x18,0x18}, + {0x0C,0x1C,0x1C}, {0x0C,0x24,0x0C}, {0x0C,0x28,0x0C}, {0x0C,0x30,0x18}, @@ -1213,21 +1218,33 @@ public class NullReferenceImplTransformations { {0x10,0x10,0x10}, {0x10,0x14,0x14}, {0x10,0x18,0x18}, + {0x10,0x1C,0x1C}, {0x10,0x24,0x14}, {0x10,0x28,0x18}, {0x10,0x30,0x10}, {0x10,0x34,0x10}, {0x14,0x14,0x14}, {0x14,0x18,0x18}, + {0x14,0x1C,0x1C}, {0x14,0x24,0x14}, {0x14,0x28,0x18}, {0x14,0x30,0x14}, {0x18,0x18,0x18}, + {0x18,0x1C,0x1C}, {0x18,0x24,0x18}, {0x18,0x28,0x18}, {0x18,0x30,0x18}, + {0x1C,0x1C,0x1C}, + {0x1C,0x20,0x1C}, + {0x1C,0x24,0x1C}, + {0x1C,0x28,0x1C}, + {0x1C,0x2C,0x1C}, + {0x1C,0x30,0x1C}, + {0x1C,0x34,0x1C}, + {0x1C,0x38,0x1C}, + {0x1C,0x3C,0x1C}, {0x24,0x24,0x24}, - {0x24,0x28,0x24}, + {0x24,0x28,0x0C}, {0x24,0x30,0x14}, {0x28,0x28,0x28}, {0x28,0x30,0x18}, 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 87c84a69d2..7322456c27 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 @@ -15,6 +15,7 @@ * bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo * bug 349326 - [1.7] new warning for missing try-with-resources * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" + * bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() *******************************************************************************/ package org.eclipse.jdt.internal.compiler.flow; @@ -1453,8 +1454,8 @@ public void markPotentiallyUnknownBit(LocalVariableBinding local) { isTrue((this.nullBit1 & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$ this.nullBit4 |= mask; if (COVERAGE_TEST_FLAG) { - if(CoverageTestId == 46) { - this.nullBit4 = ~0; + if(CoverageTestId == 44) { + this.nullBit4 = 0; } } } else { @@ -1481,8 +1482,11 @@ public void markPotentiallyUnknownBit(LocalVariableBinding local) { isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$ this.extra[5][vectorIndex] |= mask; if (COVERAGE_TEST_FLAG) { - if(CoverageTestId == 47) { - this.extra[5][vectorIndex] = ~0; + if(CoverageTestId == 45) { + this.extra[2][vectorIndex] = ~0; + this.extra[3][vectorIndex] = ~0; + this.extra[4][vectorIndex] = 0; + this.extra[5][vectorIndex] = 0; } } } @@ -1501,7 +1505,7 @@ public void markPotentiallyNullBit(LocalVariableBinding local) { this.nullBit2 |= mask; if (COVERAGE_TEST_FLAG) { if(CoverageTestId == 40) { - this.nullBit4 = ~0; + this.nullBit2 = 0; } } } else { @@ -1529,7 +1533,7 @@ public void markPotentiallyNullBit(LocalVariableBinding local) { isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'potentially null' mark in unexpected state"); //$NON-NLS-1$ if (COVERAGE_TEST_FLAG) { if(CoverageTestId == 41) { - this.extra[5][vectorIndex] = ~0; + this.extra[3][vectorIndex] = 0; } } } @@ -1548,7 +1552,10 @@ public void markPotentiallyNonNullBit(LocalVariableBinding local) { this.nullBit3 |= mask; if (COVERAGE_TEST_FLAG) { if(CoverageTestId == 42) { - this.nullBit4 = ~0; + this.nullBit1 = ~0; + this.nullBit2 = 0; + this.nullBit3 = ~0; + this.nullBit4 = 0; } } } else { @@ -1576,7 +1583,10 @@ public void markPotentiallyNonNullBit(LocalVariableBinding local) { this.extra[4][vectorIndex] |= mask; if (COVERAGE_TEST_FLAG) { if(CoverageTestId == 43) { - this.extra[5][vectorIndex] = ~0; + this.extra[2][vectorIndex] = ~0; + this.extra[3][vectorIndex] = 0; + this.extra[4][vectorIndex] = ~0; + this.extra[5][vectorIndex] = 0; } } } @@ -1628,57 +1638,27 @@ public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { this.tagBits = otherInits.tagBits; } else if (thisHadNulls) { if (otherHasNulls) { - this.nullBit1 = (a2 = this.nullBit2) & (a3 = this.nullBit3) - & (a4 = this.nullBit4) & (b1 = otherInits.nullBit1) - & (nb2 = ~(b2 = otherInits.nullBit2)) - | (a1 = this.nullBit1) & (b1 & (a3 & a4 & (b3 = otherInits.nullBit3) - & (b4 = otherInits.nullBit4) - | (na2 = ~a2) & nb2 - & ((nb4 = ~b4) | (na4 = ~a4) - | (na3 = ~a3) & (nb3 = ~b3)) - | a2 & b2 & ((na4 | na3) & (nb4 | nb3))) - | na2 & b2 & b3 & b4); - this.nullBit2 = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4) - | a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1); - this.nullBit3 = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4)) - | a3 & (na2 & a4 | na1) - | (a2 | na1) & b1 & nb2 & nb4 - | a1 & na2 & na4 & (b2 | nb1); + this.nullBit1 = (a1 = this.nullBit1) & (b1 = otherInits.nullBit1) & ( + ((a2 = this.nullBit2) & (((b2 = otherInits.nullBit2) & + ~(((a3=this.nullBit3) & (a4=this.nullBit4)) ^ ((b3=otherInits.nullBit3) & (b4=otherInits.nullBit4)))) + |(a3 & a4 & (nb2 = ~b2)))) + |((na2 = ~a2) & ((b2 & b3 & b4) + |(nb2 & ((na3 = ~a3) ^ b3))))); + this.nullBit2 = b2 & ((nb3 = ~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4 = ~b4)) + | a2 & (b2 | (na4 = ~a4) & b3 & (b4 | nb1) | na3 | na1); + this.nullBit3 = a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4)) + | b3 & (nb1 | b1 & nb2); this.nullBit4 = na3 & (nb1 & nb3 & b4 | b1 & (nb2 & nb3 | a4 & b2 & nb4) | na1 & a4 & (nb3 | b1 & b2)) - | a3 & a4 & (b3 & b4 | b1 & nb2) + | a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2) | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2 | a1 & (na3 & (nb3 & b4 | b1 & b2 & b3 & nb4 | na2 & (nb3 | nb2)) | na2 & b3 & b4 - | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3); - // the above formulae do not handle the state 0111, do it now explicitly: - long ax = ~a1 & a2 & a3 & a4; - long bx = ~b1 & b2 & b3 & b4; - long x = ax|bx; - if (x != 0) { - // restore state 0111 for all variable ids in x: - this.nullBit1 &= ~x; - this.nullBit2 |= x; - this.nullBit3 |= x; - this.nullBit4 |= x; - } - // workaround for Bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() - ax = a1 & ~a2 & a3 & ~a4; - bx = b1 & ~b2 & ~b3 & b4; - x = ax&bx; - ax = a1 & ~a2 & ~a3 & a4; - bx = b1 & ~b2 & b3 & ~b4; - x |= (ax&bx); - if (x != 0) { - // establish state 0011 for all variable ids in x: - this.nullBit1 &= ~x; - this.nullBit2 &= ~x; - this.nullBit3 |= x; - this.nullBit4 |= x; - } + | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3) + |nb1 & b2 & b3 & b4; if (COVERAGE_TEST_FLAG) { if(CoverageTestId == 30) { @@ -1798,57 +1778,27 @@ public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { } // compose nulls for (i = 0; i < mergeLimit; i++) { - this.extra[1 + 1][i] = (a2 = this.extra[2 + 1][i]) & (a3 = this.extra[3 + 1][i]) - & (a4 = this.extra[4 + 1][i]) & (b1 = otherInits.extra[1 + 1][i]) - & (nb2 = ~(b2 = otherInits.extra[2 + 1][i])) - | (a1 = this.extra[1 + 1][i]) & (b1 & (a3 & a4 & (b3 = otherInits.extra[3 + 1][i]) - & (b4 = otherInits.extra[4 + 1][i]) - | (na2 = ~a2) & nb2 - & ((nb4 = ~b4) | (na4 = ~a4) - | (na3 = ~a3) & (nb3 = ~b3)) - | a2 & b2 & ((na4 | na3) & (nb4 | nb3))) - | na2 & b2 & b3 & b4); - this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4) - | a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1); - this.extra[3 + 1][i] = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4)) - | a3 & (na2 & a4 | na1) - | (a2 | na1) & b1 & nb2 & nb4 - | a1 & na2 & na4 & (b2 | nb1); + this.extra[1 + 1][i] = (a1=this.extra[1+1][i]) & (b1=otherInits.extra[1+1][i]) & ( + ((a2=this.extra[2+1][i]) & (((b2=otherInits.extra[2+1][i]) & + ~(((a3=this.extra[3+1][i]) & (a4=this.extra[4+1][i])) ^ ((b3=otherInits.extra[3+1][i]) & (b4=otherInits.extra[4+1][i])))) + |(a3 & a4 & (nb2=~b2)))) + |((na2=~a2) & ((b2 & b3 & b4) + |(nb2 & ((na3=~a3) ^ b3))))); + this.extra[2 + 1][i] = b2 & ((nb3=~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4=~b4)) + | a2 & (b2 | (na4=~a4) & b3 & (b4 | nb1) | na3 | na1); + this.extra[3 + 1][i] = a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4)) + | b3 & (nb1 | b1 & nb2); this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4 | b1 & (nb2 & nb3 | a4 & b2 & nb4) | na1 & a4 & (nb3 | b1 & b2)) - | a3 & a4 & (b3 & b4 | b1 & nb2) + | a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2) | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2 | a1 & (na3 & (nb3 & b4 | b1 & b2 & b3 & nb4 | na2 & (nb3 | nb2)) | na2 & b3 & b4 - | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3); - // the above formulae do not handle the state 0111, do it now explicitly: - long ax = ~a1 & a2 & a3 & a4; - long bx = ~b1 & b2 & b3 & b4; - long x = ax|bx; - if (x != 0) { - // restore state 0111 for all variable ids in x: - this.extra[2][i] &= ~x; - this.extra[3][i] |= x; - this.extra[4][i] |= x; - this.extra[5][i] |= x; - } - // workaround for Bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() - ax = a1 & ~a2 & a3 & ~a4; - bx = b1 & ~b2 & ~b3 & b4; - x = ax&bx; - ax = a1 & ~a2 & ~a3 & a4; - bx = b1 & ~b2 & b3 & ~b4; - x |= (ax&bx); - if (x != 0) { - // establish state 0011 for all variable ids in x: - this.extra[2][i] &= ~x; - this.extra[3][i] &= ~x; - this.extra[4][i] |= x; - this.extra[5][i] |= x; - } + | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3) + |nb1 & b2 & b3 & b4; thisHasNulls = thisHasNulls || this.extra[3][i] != 0 || this.extra[4][i] != 0 || |