Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 39168 Details for
Bug 127570
[compiler][null] lazy initialization coding pattern within loops
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Tentative fix + tests
org.eclipse.jdt.core_head_05.txt (text/plain), 378.17 KB, created by
Maxime Daniel
on 2006-04-21 10:34:09 EDT
(
hide
)
Description:
Tentative fix + tests
Filename:
MIME Type:
Creator:
Maxime Daniel
Created:
2006-04-21 10:34:09 EDT
Size:
378.17 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java,v >retrieving revision 1.55 >diff -u -r1.55 UnconditionalFlowInfo.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 19 Apr 2006 12:26:59 -0000 1.55 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 21 Apr 2006 14:13:20 -0000 >@@ -42,27 +42,36 @@ > // never release with the coverageTestFlag set to true > public static int coverageTestId; > >+ // assignment bits - first segment > public long definiteInits; > public long potentialInits; > >- public long nullAssignmentStatusBit1; >- public long nullAssignmentStatusBit2; >- // 0 0 is potential (bit 1 is leftmost here) >- // 1 0 is assigned >- // 0 1 is protected null (aka if (o == null) { // here o protected null...) >- // 1 1 is protected non null >- public long nullAssignmentValueBit1; >- public long nullAssignmentValueBit2; >- // information only relevant for potential and assigned >- // 0 0 is start -- nothing known at all >- // 0 1 is assigned non null or potential anything but null >- // 1 0 is assigned null or potential null >- // 1 1 is potential null and potential anything but null or definite unknown >- // consider reintroducing the difference between potential non null and potential >- // unknown; if this is done, rename to nullAssignmentBit[1-4] since the semantics >- // would be ever less clear >- // went public in order to grant access to tests; do not like it... >- >+ // null bits - first segment >+ public long >+ nullBit1, >+ nullBit2, >+ nullBit3, >+ nullBit4; >+/* >+ nullBit1 >+ nullBit2... >+ 0000 start >+ 0001 pot. unknown >+ 0010 pot. non null >+ 0011 pot. nn & pot. un >+ 0100 pot. null >+ 0101 pot. n & pot. un >+ 0110 pot. n & pot. nn >+ 1001 def. unknown >+ 1010 def. non null >+ 1011 pot. nn & prot. nn >+ 1100 def. null >+ 1101 pot. n & prot. n >+ 1110 prot. null >+ 1111 prot. non null >+ */ >+ >+ // extra segments > public static final int extraLength = 6; > public long extra[][]; > // extra bit fields for larger numbers of fields/variables >@@ -71,7 +80,7 @@ > // arrays which have the same size > > public int maxFieldCount; // limit between fields and locals >- >+ > // Constants > public static final int BitCacheSize = 64; // 64 bits in a long. > >@@ -87,50 +96,54 @@ > // union of potentially set ones > this.potentialInits |= otherInits.potentialInits; > // combine null information >- // note: we may have both forms of protection (null and non null) >- // coming with otherInits, because of loops >- boolean considerNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0; >- long a1, na1, a2, na2, a3, a4, na4, b1, b2, nb2, b3, nb3, b4, nb4; >- if (considerNulls) { >- if ((this.tagBits & NULL_FLAG_MASK) == 0) { >- this.nullAssignmentStatusBit1 = otherInits.nullAssignmentStatusBit1; >- this.nullAssignmentStatusBit2 = otherInits.nullAssignmentStatusBit2; >- this.nullAssignmentValueBit1 = otherInits.nullAssignmentValueBit1; >- this.nullAssignmentValueBit2 = otherInits.nullAssignmentValueBit2; >+ boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0, >+ otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0; >+ long >+ a1, a2, a3, a4, >+ na1, na2, na3, na4, >+ b1, b2, b3, b4, >+ nb1, nb2, nb3, nb4; >+ if (otherHasNulls) { >+ if (!thisHadNulls) { >+ this.nullBit1 = otherInits.nullBit1; >+ this.nullBit2 = otherInits.nullBit2; >+ this.nullBit3 = otherInits.nullBit3; >+ this.nullBit4 = otherInits.nullBit4; > if (coverageTestFlag && coverageTestId == 1) { >- this.nullAssignmentValueBit2 = ~0; >+ this.nullBit4 = ~0; > } > } > else { >- this.nullAssignmentStatusBit1 = >- (b1 = otherInits.nullAssignmentStatusBit1) >- | ((a1 = this.nullAssignmentStatusBit1) >- & (((nb2 = ~(b2 = otherInits.nullAssignmentStatusBit2)) >- & (nb3 = ~(b3 = otherInits.nullAssignmentValueBit1)) >- & ((nb4 = ~(b4 = otherInits.nullAssignmentValueBit2)) >- | ((a2 = this.nullAssignmentStatusBit2) >- ^ (a4 = this.nullAssignmentValueBit2)))) >- | nb4 & (na2 = ~a2) & (na4 = ~a4))); >- this.nullAssignmentStatusBit2 = >- (b1 & b2) >- | (~b1 >- & ((((na1 = ~a1) | a4) & b2) >- | (a2 >- & (b2 >- | (a1 & (na4 = ~a4) & nb2 & nb3) >- | ((~(a3 = this.nullAssignmentValueBit1) & nb3) >- | (na1 & na4)) >- & nb4)))); >- this.nullAssignmentValueBit1 = >- nb2 & b3 | >- ~b1 & ((a1 & na2 & na4 | na1 & a3) & (nb2 | nb4) | >- a1 & na2 & a3 & nb2 | >- (a1 | a2 | na4) & b3); >- this.nullAssignmentValueBit2 = >- b4 | >- a4 & (nb2 & nb3 | ~(b1 ^ b2)); >+ this.nullBit1 = (b1 = otherInits.nullBit1) >+ | (a1 = this.nullBit1) & ((a3 = this.nullBit3) >+ & (a4 = this.nullBit4) & (nb2 = ~(b2 = otherInits.nullBit2)) >+ & (nb4 = ~(b4 = otherInits.nullBit4)) >+ | ((na4 = ~a4) | (na3 = ~a3)) >+ & ((na2 = ~(a2 = this.nullBit2)) & nb2 >+ | a2 & (nb3 = ~(b3 = otherInits.nullBit3)) & nb4)); >+ this.nullBit2 = b2 & (nb4 | nb3) >+ | na3 & na4 & b2 >+ | a2 & (nb3 & nb4 >+ | (nb1 = ~b1) & (na3 | (na1 = ~a1)) >+ | a1 & b2); >+ this.nullBit3 = b3 & (nb1 & (b2 | a2 | na1) >+ | b1 & (b4 | nb2 | a1 & a3) >+ | na1 & na2 & na4) >+ | a3 & nb2 & nb4 >+ | nb1 & ((na2 & a4 | na1) & a3 >+ | a1 & na2 & na4 & b2); >+ this.nullBit4 = nb1 & (a4 & (na3 & nb3 | (a3 | na2) & nb2) >+ | a1 & (a3 & nb2 & b4 >+ | a2 & b2 & (b4 | a3 & na4 & nb3))) >+ | b1 & (a3 & a4 & b4 >+ | na2 & na4 & nb3 & b4 >+ | a2 & ((b3 | a4) & b4 >+ | na3 & a4 & b2 & b3) >+ | na1 & (b4 | (a4 | a2) & b2 & b3)) >+ | (na1 & (na3 & nb3 | na2 & nb2) >+ | a1 & (nb2 & nb3 | a2 & a3)) & b4; > if (coverageTestFlag && coverageTestId == 2) { >- this.nullAssignmentValueBit2 = ~0; >+ this.nullBit4 = ~0; > } > } > this.tagBits |= NULL_FLAG_MASK; // in all cases - avoid forgetting extras >@@ -144,9 +157,6 @@ > int length, otherLength; > if ((length = this.extra[0].length) < > (otherLength = otherInits.extra[0].length)) { >- if (coverageTestFlag && coverageTestId == 3) { >- throw new AssertionFailedException("COVERAGE 3"); //$NON-NLS-1$ >- } > // current storage is shorter -> grow current > for (int j = 0; j < extraLength; j++) { > System.arraycopy(this.extra[j], 0, >@@ -154,16 +164,18 @@ > } > mergeLimit = length; > copyLimit = otherLength; >+ if (coverageTestFlag && coverageTestId == 3) { >+ throw new AssertionFailedException("COVERAGE 3"); //$NON-NLS-1$ >+ } > } else { >+ // current storage is longer >+ mergeLimit = otherLength; > if (coverageTestFlag && coverageTestId == 4) { > throw new AssertionFailedException("COVERAGE 4"); //$NON-NLS-1$ > } >- // current storage is longer >- mergeLimit = otherLength; > } > } >- } >- else if (otherInits.extra != null) { >+ } else if (otherInits.extra != null) { > // no storage here, but other has extra storage. > // shortcut regular copy because array copy is better > int otherLength; >@@ -173,7 +185,7 @@ > otherInits.extra[0].length]), 0, otherLength); > System.arraycopy(otherInits.extra[1], 0, > (this.extra[1] = new long[otherLength]), 0, otherLength); >- if (considerNulls) { >+ if (otherHasNulls) { > for (int j = 2; j < extraLength; j++) { > System.arraycopy(otherInits.extra[j], 0, > (this.extra[j] = new long[otherLength]), 0, otherLength); >@@ -187,66 +199,70 @@ > this.extra[j] = new long[otherLength]; > } > if (coverageTestFlag && coverageTestId == 6) { >- this.extra[5][otherLength - 1] = ~0; >+ throw new AssertionFailedException("COVERAGE 6"); //$NON-NLS-1$ > } > } > } >- int i = 0; >- for (; i < mergeLimit; i++) { >+ int i; >+ // manage definite assignment info >+ for (i = 0; i < mergeLimit; i++) { > this.extra[0][i] |= otherInits.extra[0][i]; > this.extra[1][i] |= otherInits.extra[1][i]; >- if (considerNulls) { // could consider pushing the test outside the loop >- if (this.extra[2][i] == 0 && >- this.extra[3][i] == 0 && >- this.extra[4][i] == 0 && >- this.extra[5][i] == 0) { >- for (int j = 2; j < extraLength; j++) { >- this.extra[j][i] = otherInits.extra[j][i]; >- } >- if (coverageTestFlag && coverageTestId == 7) { >- this.extra[5][i] = ~0; >- } >- } >- else { >- this.extra[2][i] = >- (b1 = otherInits.extra[2][i]) | >- (a1 = this.extra[2][i]) & >- ((nb2 = ~(b2 = otherInits.extra[3][i])) & >- (nb3 = ~(b3 = otherInits.extra[4][i])) & >- ((nb4 = ~(b4 = otherInits.extra[5][i])) | >- ((a2 = this.extra[3][i]) ^ >- (a4 = this.extra[5][i]))) | >- nb4 & (na2 = ~a2) & (na4 = ~a4)); >- this.extra[3][i] = >- b1 & b2 | >- ~b1 & (((na1 = ~a1) | a4) & b2 | >- a2 & (b2 | >- a1 & (na4 = ~a4) & nb2 & nb3 | >- (~(a3 = this.extra[4][i]) & nb3 | na1 & na4) & nb4)); >- this.extra[4][i] = >- nb2 & b3 | >- ~b1 & ((a1 & na2 & na4 | na1 & a3) & (nb2 | nb4) | >- a1 & na2 & a3 & nb2 | >- (a1 | a2 | na4) & b3); >- this.extra[5][i] = >- b4 | >- a4 & (nb2 & nb3 | ~(b1 ^ b2)); >- if (coverageTestFlag && coverageTestId == 8) { >- this.extra[5][i] = ~0; >- } >- } >- } > } > for (; i < copyLimit; i++) { > this.extra[0][i] = otherInits.extra[0][i]; > this.extra[1][i] = otherInits.extra[1][i]; >- if (considerNulls) { >- for (int j = 2; j < extraLength; j++) { >- this.extra[j][i] = otherInits.extra[j][i]; >- } >- if (coverageTestFlag && coverageTestId == 9) { >- this.extra[5][i] = ~0; >- } >+ } >+ // tweak limits for nulls >+ if (!thisHadNulls) { >+ if (copyLimit < mergeLimit) { >+ copyLimit = mergeLimit; >+ } >+ mergeLimit = 0; >+ } >+ if (!otherHasNulls) { >+ copyLimit = 0; >+ mergeLimit = 0; >+ } >+ for (i = 0; i < mergeLimit; i++) { >+ this.extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i]) >+ | (a1 = this.extra[1 + 1][i]) & ((a3 = this.extra[3 + 1][i]) >+ & (a4 = this.extra[4 + 1][i]) & (nb2 = ~(b2 = otherInits.extra[2 + 1][i])) >+ & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) >+ | ((na4 = ~a4) | (na3 = ~a3)) >+ & ((na2 = ~(a2 = this.extra[2 + 1][i])) & nb2 >+ | a2 & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])) & nb4)); >+ this.extra[2 + 1][i] = b2 & (nb4 | nb3) >+ | na3 & na4 & b2 >+ | a2 & (nb3 & nb4 >+ | (nb1 = ~b1) & (na3 | (na1 = ~a1)) >+ | a1 & b2); >+ this.extra[3 + 1][i] = b3 & (nb1 & (b2 | a2 | na1) >+ | b1 & (b4 | nb2 | a1 & a3) >+ | na1 & na2 & na4) >+ | a3 & nb2 & nb4 >+ | nb1 & ((na2 & a4 | na1) & a3 >+ | a1 & na2 & na4 & b2); >+ this.extra[4 + 1][i] = nb1 & (a4 & (na3 & nb3 | (a3 | na2) & nb2) >+ | a1 & (a3 & nb2 & b4 >+ | a2 & b2 & (b4 | a3 & na4 & nb3))) >+ | b1 & (a3 & a4 & b4 >+ | na2 & na4 & nb3 & b4 >+ | a2 & ((b3 | a4) & b4 >+ | na3 & a4 & b2 & b3) >+ | na1 & (b4 | (a4 | a2) & b2 & b3)) >+ | (na1 & (na3 & nb3 | na2 & nb2) >+ | a1 & (nb2 & nb3 | a2 & a3)) & b4; >+ if (coverageTestFlag && coverageTestId == 7) { >+ this.extra[5][i] = ~0; >+ } >+ } >+ for (; i < copyLimit; i++) { >+ for (int j = 2; j < extraLength; j++) { >+ this.extra[j][i] = otherInits.extra[j][i]; >+ } >+ if (coverageTestFlag && coverageTestId == 8) { >+ this.extra[5][i] = ~0; > } > } > } >@@ -322,206 +338,126 @@ > return this; > } > // if we get here, otherInits has some null info >- boolean thisHasNulls = (this.tagBits & NULL_FLAG_MASK) != 0; >- if (thisHasNulls) { >- long a1, a2, na2, a3, na3, a4, na4, b1, nb1, b2, nb2, b3, nb3, b4, nb4; >- this.nullAssignmentStatusBit1 = >- ((a1 = this.nullAssignmentStatusBit1) & >- (na4 = ~(a4 = this.nullAssignmentValueBit2)) & >- ((na3 = ~(a3 = this.nullAssignmentValueBit1)) | >- (a2 = this.nullAssignmentStatusBit2)) | >- a2 & na3 & a4) & >- (nb3 = ~(b3 = otherInits.nullAssignmentValueBit1)) & >- ((b2 = otherInits.nullAssignmentStatusBit2) | >- (nb4 = ~(b4 = otherInits.nullAssignmentValueBit2))) | >- a1 & (na2 = ~a2) & >- (a4 & ((nb1 = ~(b1 = otherInits.nullAssignmentStatusBit1)) & >- nb3 | b1 & >- (b4 | b2)) | >- na4 & (nb1 & (((nb2 = ~b2) & nb4 | b2) & nb3 | b3 & nb4) | >- b1 & nb4 & (nb2 | nb3))); >- this.nullAssignmentStatusBit2 = >- a2 & (~a1 & na4 & nb4 | >- a1 & na3 & nb3 & (nb1 & (nb2 & nb4 | b2) | >- b1 & (nb4 |b2 & b4))); >- this.nullAssignmentValueBit1 = >- a3 | >- b1 & nb2 & nb4 | >- nb1 & b3 | >- a1 & na2 & (b1 & b3 | nb1 & b4); >-// b1 & (~b2 & ~b4 | a1 & ~a2 & b3) | >-// ~b1 & (b3 | a1 & ~a2 & b4); -- same op nb >- this.nullAssignmentValueBit2 = >- a4 & (na2 | a2 & na3) | >- b4 & (nb2 | b2 & nb3); >- if (coverageTestFlag && coverageTestId == 15) { >- this.nullAssignmentValueBit2 = ~0; >- } >- // extra storage management >- if (otherInits.extra != null) { >- int mergeLimit = 0, copyLimit = 0; >- int otherLength = otherInits.extra[0].length; >- if (this.extra == null) { >- this.extra = new long[extraLength][]; >- for (int j = 0; j < extraLength; j++) { >- this.extra[j] = new long[otherLength]; >- } >- copyLimit = otherLength; >- if (coverageTestFlag && coverageTestId == 16) { >- this.extra[2][0] = ~0; thisHasNulls = true; >- } >- } >- else { >- mergeLimit = otherLength; >- if (mergeLimit > this.extra[0].length) { >- copyLimit = mergeLimit; >- mergeLimit = this.extra[0].length; >- for (int j = 0; j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- this.extra[j] = new long[otherLength], 0, >- mergeLimit); >- } >- } >- int i; >- for (i = 0; i < mergeLimit; i++) { >- this.extra[2][i] = >- ((a1 = this.extra[2][i]) & >- (na4 = ~(a4 = this.extra[5][i])) & >- ((na3 = ~(a3 = this.extra[4][i])) | >- (a2 = this.extra[3][i])) | >- a2 & na3 & a4) & >- (nb3 = ~(b3 = otherInits.extra[4][i])) & >- ((b2 = otherInits.extra[3][i]) | >- (nb4 = ~(b4 = otherInits.extra[5][i]))) | >- a1 & (na2 = ~a2) & >- (a4 & ((nb1 = ~(b1 = otherInits.extra[2][i])) & >- nb3 | b1 & >- (b4 | b2)) | >- na4 & (nb1 & (((nb2 = ~b2) & nb4 | b2) & nb3 | b3 & nb4) | >- b1 & nb4 & (nb2 | nb3))); >- this.extra[3][i] = >- a2 & (~a1 & na4 & nb4 | >- a1 & na3 & nb3 & (nb1 & (nb2 & nb4 | b2) | >- b1 & (nb4 |b2 & b4))); >- this.extra[4][i] = >- a3 | >- b1 & nb2 & nb4 | >- nb1 & b3 | >- a1 & na2 & (b1 & b3 | nb1 & b4); >- this.extra[5][i] = >- a4 & (na2 | a2 & na3) | >- b4 & (nb2 | b2 & nb3); >- if (coverageTestFlag && coverageTestId == 17) { >- this.nullAssignmentValueBit2 = ~0; >- } >- } >- for (; i < copyLimit; i++) { >- if (otherInits.extra[4][i] != 0 || >- otherInits.extra[5][i] != 0) { >- this.tagBits |= NULL_FLAG_MASK; >- this.extra[4][i] = >- otherInits.extra[4][i] & >- ~(otherInits.extra[2][i] & >- ~otherInits.extra[3][i] & >- otherInits.extra[5][i]); >- this.extra[5][i] = >- otherInits.extra[5][i]; >- if (coverageTestFlag && coverageTestId == 18) { >- this.extra[5][i] = ~0; >- } >- } >- } >+ boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0, >+ thisHasNulls = false; >+ long a1, a2, a3, a4, >+ na1, na2, na3, na4, >+ b1, b2, b3, b4, >+ nb1, nb2, nb3, nb4; >+ if (thisHadNulls) { >+ this.nullBit1 = (a1 = this.nullBit1) >+ & ((a3 = this.nullBit3) & (a4 = this.nullBit4) >+ & ((nb2 = ~(b2 = otherInits.nullBit2)) >+ & (nb4 = ~(b4 = otherInits.nullBit4)) >+ | (b1 = otherInits.nullBit1) & (b3 = otherInits.nullBit3)) >+ | (na2 = ~(a2 = this.nullBit2)) >+ & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2) >+ | a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2))); >+ this.nullBit2 = b2 & (nb3 | (nb1 = ~b1)) >+ | a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1)); >+ this.nullBit3 = b3 & (nb1 & b2 >+ | a2 & (nb2 | a3) >+ | na1 & nb2 >+ | a1 & na2 & na4 & b1) >+ | a3 & (nb2 & nb4 | na2 & a4 | na1) >+ | a1 & na2 & na4 & b2; >+ this.nullBit4 = na3 & (nb1 & nb3 & b4 >+ | a4 & (nb3 | b1 & b2)) >+ | nb2 & (na3 & b1 & nb3 | na2 & (nb1 & b4 | b1 & nb3 | a4)) >+ | a3 & (a4 & (nb2 | b1 & b3) >+ | a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3)); >+ if (coverageTestFlag && coverageTestId == 9) { >+ this.nullBit4 = ~0; >+ } >+ if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { // bit1 is redundant >+ thisHasNulls = true; >+ } >+ } else { >+ this.nullBit1 = 0; >+ this.nullBit2 = (b2 = otherInits.nullBit2) >+ & ((nb3 = ~(b3 = otherInits.nullBit3)) | >+ (nb1 = ~(b1 = otherInits.nullBit1))); >+ this.nullBit3 = b3 & (nb1 | (nb2 = ~b2)); >+ this.nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4) | ~b2 & (b1 & ~b3 | ~b1 & b4); >+ if (coverageTestFlag && coverageTestId == 10) { >+ this.nullBit4 = ~0; >+ } >+ if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { // bit1 is redundant >+ thisHasNulls = true; >+ } >+ } >+ // extra storage management >+ if (otherInits.extra != null) { >+ int mergeLimit = 0, copyLimit = otherInits.extra[0].length; >+ if (this.extra == null) { >+ this.extra = new long[extraLength][]; >+ for (int j = 0; j < extraLength; j++) { >+ this.extra[j] = new long[copyLimit]; > } >- } >- } >- else { >- if (otherInits.nullAssignmentValueBit1 != 0 || >- otherInits.nullAssignmentValueBit2 != 0) { >- // add potential values >- this.nullAssignmentValueBit1 = >- otherInits.nullAssignmentValueBit1 & >- ~(otherInits.nullAssignmentStatusBit1 & >- ~otherInits.nullAssignmentStatusBit2 & >- otherInits.nullAssignmentValueBit2); // exclude assigned unknown >- this.nullAssignmentValueBit2 = >- otherInits.nullAssignmentValueBit2; >- thisHasNulls = >- this.nullAssignmentValueBit1 != 0 || >- this.nullAssignmentValueBit2 != 0; >- if (coverageTestFlag && coverageTestId == 10) { >- this.nullAssignmentValueBit2 = ~0; >+ if (coverageTestFlag && coverageTestId == 11) { >+ throw new AssertionFailedException("COVERAGE 11"); //$NON-NLS-1$ > } >- } >- // extra storage management >- if (otherInits.extra != null) { >- int mergeLimit = 0, copyLimit = 0; >- int otherLength = otherInits.extra[0].length; >- if (this.extra == null) { >- copyLimit = otherLength; >- // cannot happen when called from addPotentialInitializationsFrom >- this.extra = new long[extraLength][]; >+ } else { >+ mergeLimit = copyLimit; >+ if (mergeLimit > this.extra[0].length) { >+ mergeLimit = this.extra[0].length; > for (int j = 0; j < extraLength; j++) { >- this.extra[j] = new long[otherLength]; >- } >- if (coverageTestFlag && coverageTestId == 11) { >- this.extra[5][0] = ~0; this.tagBits |= NULL_FLAG_MASK; >- } >- } >- else { >- mergeLimit = otherLength; >- if (mergeLimit > this.extra[0].length) { >- copyLimit = mergeLimit; >- mergeLimit = this.extra[0].length; >- System.arraycopy(this.extra[0], 0, >- this.extra[0] = new long[otherLength], 0, >+ System.arraycopy(this.extra[j], 0, >+ this.extra[j] = new long[copyLimit], 0, > mergeLimit); >- System.arraycopy(this.extra[1], 0, >- this.extra[1] = new long[otherLength], 0, >- mergeLimit); >- for (int j = 2; j < extraLength; j++) { >- this.extra[j] = new long[otherLength]; >- } >- if (coverageTestFlag && coverageTestId == 12) { >+ } >+ if (! thisHadNulls) { >+ mergeLimit = 0; >+ // will do with a copy -- caveat: only valid because definite assignment bits copied above >+ if (coverageTestFlag && coverageTestId == 12) { > throw new AssertionFailedException("COVERAGE 12"); //$NON-NLS-1$ >- } >+ } > } > } >- int i; >- for (i = 0; i < mergeLimit; i++) { >- if (otherInits.extra[4][i] != 0 || >- otherInits.extra[5][i] != 0) { >- this.extra[4][i] |= >- otherInits.extra[4][i] & >- ~(otherInits.extra[2][i] & >- ~otherInits.extra[3][i] & >- otherInits.extra[5][i]); >- this.extra[5][i] |= >- otherInits.extra[5][i]; >- thisHasNulls = thisHasNulls || >- this.extra[4][i] != 0 || >- this.extra[5][i] != 0; >- if (coverageTestFlag && coverageTestId == 13) { >- this.extra[5][i] = ~0; >- } >- } >+ } >+ // PREMATURE skip operations for fields >+ int i; >+ for (i = 0 ; i < mergeLimit ; i++) { >+ this.extra[1 + 1][i] = (a1 = this.extra[1 + 1][i]) >+ & ((a3 = this.extra[3 + 1][i]) & (a4 = this.extra[4 + 1][i]) >+ & ((nb2 = ~(b2 = otherInits.extra[2 + 1][i])) >+ & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) >+ | (b1 = otherInits.extra[1 + 1][i]) & (b3 = otherInits.extra[3 + 1][i])) >+ | (na2 = ~(a2 = this.extra[2 + 1][i])) >+ & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2) >+ | a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2))); >+ this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1)) >+ | a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1)); >+ this.extra[3 + 1][i] = b3 & (nb1 & b2 >+ | a2 & (nb2 | a3) >+ | na1 & nb2 >+ | a1 & na2 & na4 & b1) >+ | a3 & (nb2 & nb4 | na2 & a4 | na1) >+ | a1 & na2 & na4 & b2; >+ this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4 >+ | a4 & (nb3 | b1 & b2)) >+ | nb2 & (na3 & b1 & nb3 | na2 & (nb1 & b4 | b1 & nb3 | a4)) >+ | a3 & (a4 & (nb2 | b1 & b3) >+ | a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3)); >+ if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { // bit1 is redundant >+ thisHasNulls = true; >+ } >+ if (coverageTestFlag && coverageTestId == 13) { >+ this.nullBit4 = ~0; > } >- for (; i < copyLimit; i++) { >- if (otherInits.extra[4][i] != 0 || >- otherInits.extra[5][i] != 0) { >- this.extra[4][i] = >- otherInits.extra[4][i] & >- ~(otherInits.extra[2][i] & >- ~otherInits.extra[3][i] & >- otherInits.extra[5][i]); >- this.extra[5][i] = >- otherInits.extra[5][i]; >- thisHasNulls = thisHasNulls || >- this.extra[4][i] != 0 || >- this.extra[5][i] != 0; >- if (coverageTestFlag && coverageTestId == 14) { >- this.extra[5][i] = ~0; >- } >- } >+ } >+ for (; i < copyLimit; i++) { >+ this.extra[1 + 1][i] = 0; >+ this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) >+ & ((nb3 = ~(b3 = otherInits.extra[3 + 1][i])) | >+ (nb1 = ~(b1 = otherInits.extra[1 + 1][i]))); >+ this.extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2)); >+ this.extra[4 + 1][i] = ~b1 & ~b3 & (b4 = otherInits.extra[4 + 1][i]) | ~b2 & (b1 & ~b3 | ~b1 & b4); >+ if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { // bit1 is redundant >+ thisHasNulls = true; >+ } >+ if (coverageTestFlag && coverageTestId == 14) { >+ this.extra[5][i] = ~0; > } > } > } >@@ -545,10 +481,10 @@ > copy.potentialInits = this.potentialInits; > boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0; > if (hasNullInfo) { >- copy.nullAssignmentStatusBit1 = this.nullAssignmentStatusBit1; >- copy.nullAssignmentStatusBit2 = this.nullAssignmentStatusBit2; >- copy.nullAssignmentValueBit1 = this.nullAssignmentValueBit1; >- copy.nullAssignmentValueBit2 = this.nullAssignmentValueBit2; >+ copy.nullBit1 = this.nullBit1; >+ copy.nullBit2 = this.nullBit2; >+ copy.nullBit3 = this.nullBit3; >+ copy.nullBit4 = this.nullBit4; > } > copy.tagBits = this.tagBits; > copy.maxFieldCount = this.maxFieldCount; >@@ -604,10 +540,10 @@ > long mask = (1L << limit)-1; > this.definiteInits &= mask; > this.potentialInits &= mask; >- this.nullAssignmentStatusBit1 &= mask; >- this.nullAssignmentStatusBit2 &= mask; >- this.nullAssignmentValueBit1 &= mask; >- this.nullAssignmentValueBit2 &= mask; >+ this.nullBit1 &= mask; >+ this.nullBit2 &= mask; >+ this.nullBit3 &= mask; >+ this.nullBit4 &= mask; > } > // use extra vector > if (this.extra == null) { >@@ -694,15 +630,9 @@ > return true; > } > int position = local.id + this.maxFieldCount; >- long mask; > if (position < BitCacheSize) { // use bits >- return >- (this.nullAssignmentStatusBit2 & >- (mask = 1L << position)) != 0 ? >- (this.nullAssignmentStatusBit1 & mask) != 0 : >- (this.nullAssignmentStatusBit1 & >- this.nullAssignmentValueBit2 & mask) != 0 && >- (this.nullAssignmentValueBit1 & mask) == 0; >+ return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4)) >+ & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -713,13 +643,9 @@ > >= this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return >- (this.extra[3][vectorIndex] & >- (mask = 1L << (position % BitCacheSize))) != 0 ? >- (this.extra[2][vectorIndex] & mask) != 0 : >- (this.extra[2][vectorIndex] & >- this.extra[5][vectorIndex] & mask) != 0 && >- (this.extra[4][vectorIndex] & mask) == 0; >+ return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex] >+ & (~this.extra[3][vectorIndex] | this.extra[5][vectorIndex])) >+ & (1L << (position % BitCacheSize))) != 0; > } > > final public boolean isDefinitelyNull(LocalVariableBinding local) { >@@ -730,14 +656,10 @@ > return false; > } > int position = local.id + this.maxFieldCount; >- long mask; > if (position < BitCacheSize) { // use bits >- return >- (this.nullAssignmentStatusBit2 & (mask = 1L << position)) != 0 ? >- (this.nullAssignmentStatusBit1 & mask) == 0 : >- (this.nullAssignmentStatusBit1 & >- this.nullAssignmentValueBit1 & mask) != 0 && >- (this.nullAssignmentValueBit2 & mask) == 0; >+ return ((this.nullBit1 & this.nullBit2 >+ & (~this.nullBit3 | ~this.nullBit4)) >+ & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -748,13 +670,9 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return >- (this.extra[3][vectorIndex] & >- (mask = 1L << (position % BitCacheSize))) != 0 ? >- (this.extra[2][vectorIndex] & mask) == 0 : >- (this.extra[2][vectorIndex] & >- this.extra[4][vectorIndex] & mask) != 0 && >- (this.extra[5][vectorIndex] & mask) == 0; >+ return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex] >+ & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex])) >+ & (1L << (position % BitCacheSize))) != 0; > } > > final public boolean isDefinitelyUnknown(LocalVariableBinding local) { >@@ -764,14 +682,9 @@ > return false; > } > int position = local.id + this.maxFieldCount; >- long mask; > if (position < BitCacheSize) { // use bits >- return >- (this.nullAssignmentStatusBit2 & (mask = 1L << position)) != 0 ? >- false : >- (this.nullAssignmentStatusBit1 & >- this.nullAssignmentValueBit1 & >- this.nullAssignmentValueBit2 & mask) != 0; >+ return ((this.nullBit1 & this.nullBit4 >+ & ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -782,14 +695,9 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return >- (this.extra[3][vectorIndex] & >- (mask = 1L << (position % BitCacheSize))) != 0 ? >- false : >- (this.extra[2][vectorIndex] & >- this.extra[4][vectorIndex] & >- this.extra[5][vectorIndex] & >- mask) != 0; >+ return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex] >+ & ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex]) >+ & (1L << (position % BitCacheSize))) != 0; > } > > /** >@@ -826,22 +734,41 @@ > return isPotentiallyAssigned(local.id + this.maxFieldCount); > } > >+final public boolean isPotentiallyNonNull(LocalVariableBinding local) { >+ if ((this.tagBits & NULL_FLAG_MASK) == 0 || >+ (local.type.tagBits & TagBits.IsBaseType) != 0) { >+ return false; >+ } >+ int position; >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { >+ // use bits >+ return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2)) >+ & (1L << position)) != 0; >+ } >+ // use extra vector >+ if (this.extra == null) { >+ return false; // if vector not yet allocated, then not initialized >+ } >+ int vectorIndex; >+ if ((vectorIndex = (position / BitCacheSize) - 1) >= >+ this.extra[0].length) { >+ return false; // if not enough room in vector, then not initialized >+ } >+ return ((this.extra[4][vectorIndex] >+ & (~this.extra[2][vectorIndex] | ~this.extra[3][vectorIndex])) >+ & (1L << (position % BitCacheSize))) != 0; >+} >+ > final public boolean isPotentiallyNull(LocalVariableBinding local) { > if ((this.tagBits & NULL_FLAG_MASK) == 0 || > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } > int position; >- long mask; > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- return >- (this.nullAssignmentStatusBit2 & (mask = 1L << position)) != 0 ? >- (this.nullAssignmentStatusBit1 & mask) == 0 : // protected null >- (this.nullAssignmentValueBit1 & mask) != 0 && // null bit set and >- ((this.nullAssignmentStatusBit1 & mask) == 0 || // (potential or >- (this.nullAssignmentValueBit2 & mask) == 0); >- // assigned, but not unknown) >+ return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3)) >+ & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -852,13 +779,9 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return >- (this.extra[3][vectorIndex] & >- (mask = 1L << (position % BitCacheSize))) != 0 ? >- (this.extra[2][vectorIndex] & mask) == 0 : >- (this.extra[4][vectorIndex] & mask) != 0 && >- ((this.extra[2][vectorIndex] & mask) == 0 || >- (this.extra[5][vectorIndex] & mask) == 0); >+ return ((this.extra[3][vectorIndex] >+ & (~this.extra[2][vectorIndex] | ~this.extra[4][vectorIndex])) >+ & (1L << (position % BitCacheSize))) != 0; > } > > final public boolean isPotentiallyUnknown(LocalVariableBinding local) { >@@ -868,16 +791,10 @@ > return false; > } > int position = local.id + this.maxFieldCount; >- long mask; > if (position < BitCacheSize) { // use bits >- return >- (this.nullAssignmentStatusBit2 & (mask = 1L << position)) != 0 ? >- false : >- ((this.nullAssignmentStatusBit1 & >- this.nullAssignmentValueBit1 | >- ~this.nullAssignmentStatusBit1 & >- ~this.nullAssignmentValueBit1) & >- this.nullAssignmentValueBit2 & mask) != 0; >+ return (this.nullBit4 >+ & (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3) >+ & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -888,16 +805,10 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return >- (this.extra[3][vectorIndex] & >- (mask = 1L << (position % BitCacheSize))) != 0 ? >- false : >- ((this.extra[2][vectorIndex] & >- this.extra[4][vectorIndex] | >- ~this.extra[2][vectorIndex] & >- ~this.extra[4][vectorIndex]) & >- this.extra[5][vectorIndex] & >- mask) != 0; >+ return (this.extra[5][vectorIndex] >+ & (~this.extra[2][vectorIndex] >+ | ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex]) >+ & (1L << (position % BitCacheSize))) != 0; > } > > final public boolean isProtectedNonNull(LocalVariableBinding local) { >@@ -908,8 +819,7 @@ > int position; > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- return (this.nullAssignmentStatusBit1 & >- this.nullAssignmentStatusBit2 & (1L << position)) != 0; >+ return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -920,9 +830,10 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return (this.extra[2][vectorIndex] & >- this.extra[3][vectorIndex] & >- (1L << (position % BitCacheSize))) != 0; >+ return (this.extra[2][vectorIndex] >+ & this.extra[4][vectorIndex] >+ & this.extra[5][vectorIndex] >+ & (1L << (position % BitCacheSize))) != 0; > } > > final public boolean isProtectedNull(LocalVariableBinding local) { >@@ -933,8 +844,9 @@ > int position; > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- return (~this.nullAssignmentStatusBit1 & >- this.nullAssignmentStatusBit2 & (1L << position)) != 0; >+ return (this.nullBit1 & this.nullBit2 >+ & (this.nullBit3 ^ this.nullBit4) >+ & (1L << position)) != 0; > } > // use extra vector > if (this.extra == null) { >@@ -945,9 +857,9 @@ > this.extra[0].length) { > return false; // if not enough room in vector, then not initialized > } >- return (~this.extra[2][vectorIndex] & >- this.extra[3][vectorIndex] & >- (1L << (position % BitCacheSize))) != 0; >+ return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex] >+ & (this.extra[4][vectorIndex] ^ this.extra[5][vectorIndex]) >+ & (1L << (position % BitCacheSize))) != 0; > } > > public void markAsComparedEqualToNonNull(LocalVariableBinding local) { >@@ -956,25 +868,32 @@ > this.tagBits |= NULL_FLAG_MASK; > int position; > long mask; >+ long a1, a2, a3, a4, na2; > // position is zero-based > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- if (((mask = 1L << position) & // leave assigned non null unchanged >- this.nullAssignmentStatusBit1 & >- ~this.nullAssignmentStatusBit2 & >- ~this.nullAssignmentValueBit1 & >- this.nullAssignmentValueBit2) == 0) { >- // set protected non null >- this.nullAssignmentStatusBit1 |= mask; >- this.nullAssignmentStatusBit2 |= mask; >- // clear potential null >- this.nullAssignmentValueBit1 &= ~mask; >- if (coverageTestFlag && coverageTestId == 19) { >- this.nullAssignmentValueBit2 = ~0; >- } >- } >- if (coverageTestFlag && coverageTestId == 20) { >- this.nullAssignmentValueBit2 = ~0; >+ if (((mask = 1L << position) >+ & (a1 = this.nullBit1) >+ & (na2 = ~(a2 = this.nullBit2)) >+ & ~(a3 = this.nullBit3) >+ & (a4 = this.nullBit4)) >+ != 0) { >+ this.nullBit4 &= ~mask; >+ } else if ((mask & a1 & na2 & a3) == 0) { >+ this.nullBit4 |= mask; >+ if ((mask & a1) == 0) { >+ if ((mask & a2 & (a3 ^ a4)) != 0) { >+ this.nullBit2 &= ~mask; >+ } >+ else if ((mask & (a2 | a3 | a4)) == 0) { >+ this.nullBit2 |= mask; >+ } >+ } >+ } >+ this.nullBit1 |= mask; >+ this.nullBit3 |= mask; >+ if (coverageTestFlag && coverageTestId == 15) { >+ this.nullBit4 = ~0; > } > } > else { >@@ -986,8 +905,8 @@ > for (int j = 0; j < extraLength; j++) { > this.extra[j] = new long[length]; > } >- if (coverageTestFlag && coverageTestId == 21) { >- throw new AssertionFailedException("COVERAGE 21"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 16) { >+ throw new AssertionFailedException("COVERAGE 16"); //$NON-NLS-1$ > } > } > else { >@@ -999,22 +918,34 @@ > (this.extra[j] = new long[newLength]), 0, > oldLength); > } >- if (coverageTestFlag && coverageTestId == 22) { >- throw new AssertionFailedException("COVERAGE 22"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 17) { >+ throw new AssertionFailedException("COVERAGE 17"); //$NON-NLS-1$ > } > } > } >- if (((mask = 1L << (position % BitCacheSize)) & >- this.extra[2][vectorIndex] & >- ~this.extra[3][vectorIndex] & >- ~this.extra[4][vectorIndex] & >- this.extra[5][vectorIndex]) == 0) { >- this.extra[2][vectorIndex] |= mask; >- this.extra[3][vectorIndex] |= mask; >- this.extra[4][vectorIndex] &= ~mask; >- if (coverageTestFlag && coverageTestId == 23) { >- this.extra[5][vectorIndex] = ~0; >- } >+ // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][vectorIndex]/gc >+ if (((mask = 1L << (position % BitCacheSize)) >+ & (a1 = this.extra[1 + 1][vectorIndex]) >+ & (na2 = ~(a2 = this.extra[2 + 1][vectorIndex])) >+ & ~(a3 = this.extra[3 + 1][vectorIndex]) >+ & (a4 = this.extra[4 + 1][vectorIndex])) >+ != 0) { >+ this.extra[4 + 1][vectorIndex] &= ~mask; >+ } else if ((mask & a1 & na2 & a3) == 0) { >+ this.extra[4 + 1][vectorIndex] |= mask; >+ if ((mask & a1) == 0) { >+ if ((mask & a2 & (a3 ^ a4)) != 0) { >+ this.extra[2 + 1][vectorIndex] &= ~mask; >+ } >+ else if ((mask & (a2 | a3 | a4)) == 0) { >+ this.extra[2 + 1][vectorIndex] |= mask; >+ } >+ } >+ } >+ this.extra[1 + 1][vectorIndex] |= mask; >+ this.extra[3 + 1][vectorIndex] |= mask; >+ if (coverageTestFlag && coverageTestId == 18) { >+ this.extra[5][vectorIndex] = ~0; > } > } > } >@@ -1025,33 +956,30 @@ > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; > int position; >- long mask, unknownAssigned; >+ long mask; > // position is zero-based > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- mask = 1L << position; >- if ((mask & // leave assigned null unchanged >- this.nullAssignmentStatusBit1 & >- ~this.nullAssignmentStatusBit2 & >- this.nullAssignmentValueBit1 & >- ~this.nullAssignmentValueBit2) == 0) { >- unknownAssigned = this.nullAssignmentStatusBit1 & >- ~this.nullAssignmentStatusBit2 & >- this.nullAssignmentValueBit1 & >- this.nullAssignmentValueBit2; >- // set protected >- this.nullAssignmentStatusBit2 |= mask; >- this.nullAssignmentStatusBit1 &= (mask = ~mask); >- // protected is null >- this.nullAssignmentValueBit1 &= mask | ~unknownAssigned; >- this.nullAssignmentValueBit2 &= mask; >- // clear potential anything but null >- if (coverageTestFlag && coverageTestId == 24) { >- this.nullAssignmentValueBit2 = ~0; >- } >- } >- if (coverageTestFlag && coverageTestId == 25) { >- this.nullAssignmentValueBit2 = ~0; >+ if (((mask = 1L << position) & this.nullBit1) != 0) { >+ if ((mask >+ & (~this.nullBit2 | this.nullBit3 >+ | ~this.nullBit4)) != 0) { >+ this.nullBit4 &= ~mask; >+ } >+ } else if ((mask & this.nullBit4) != 0) { >+ this.nullBit3 &= ~mask; >+ } else { >+ if ((mask & this.nullBit2) != 0) { >+ this.nullBit3 &= ~mask; >+ this.nullBit4 |= mask; >+ } else { >+ this.nullBit3 |= mask; >+ } >+ } >+ this.nullBit1 |= mask; >+ this.nullBit2 |= mask; >+ if (coverageTestFlag && coverageTestId == 19) { >+ this.nullBit4 = ~0; > } > } > else { >@@ -1064,8 +992,8 @@ > for (int j = 0; j < extraLength; j++) { > this.extra[j] = new long[length ]; > } >- if (coverageTestFlag && coverageTestId == 26) { >- throw new AssertionFailedException("COVERAGE 26"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 20) { >+ throw new AssertionFailedException("COVERAGE 20"); //$NON-NLS-1$ > } > } > else { >@@ -1077,28 +1005,29 @@ > (this.extra[j] = new long[newLength]), 0, > oldLength); > } >- if (coverageTestFlag && coverageTestId == 27) { >- throw new AssertionFailedException("COVERAGE 27"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 21) { >+ throw new AssertionFailedException("COVERAGE 21"); //$NON-NLS-1$ > } > } > } >- if ((mask & >- this.extra[2][vectorIndex] & >- ~this.extra[3][vectorIndex] & >- this.extra[4][vectorIndex] & >- ~this.extra[5][vectorIndex]) == 0) { >- unknownAssigned = this.extra[2][vectorIndex] & >- ~this.extra[3][vectorIndex] & >- this.extra[4][vectorIndex] & >- this.extra[5][vectorIndex]; >- this.extra[3][vectorIndex] |= mask; >- this.extra[2][vectorIndex] &= (mask = ~mask); >- this.extra[4][vectorIndex] &= mask | ~unknownAssigned; >- this.extra[5][vectorIndex] &= mask; >- if (coverageTestFlag && coverageTestId == 28) { >- this.extra[5][vectorIndex] = ~0; >- } >+ if ((mask & this.extra[1 + 1][vectorIndex]) != 0) { >+ if ((mask >+ & (~this.extra[2 + 1][vectorIndex] | this.extra[3 + 1][vectorIndex] >+ | ~this.extra[4 + 1][vectorIndex])) != 0) { >+ this.extra[4 + 1][vectorIndex] &= ~mask; >+ } >+ } else if ((mask & this.extra[4 + 1][vectorIndex]) != 0) { >+ this.extra[3 + 1][vectorIndex] &= ~mask; >+ } else { >+ if ((mask & this.extra[2 + 1][vectorIndex]) != 0) { >+ this.extra[3 + 1][vectorIndex] &= ~mask; >+ this.extra[4 + 1][vectorIndex] |= mask; >+ } else { >+ this.extra[3 + 1][vectorIndex] |= mask; >+ } > } >+ this.extra[1 + 1][vectorIndex] |= mask; >+ this.extra[2 + 1][vectorIndex] |= mask; > } > } > } >@@ -1157,62 +1086,66 @@ > public void markAsDefinitelyNonNull(LocalVariableBinding local) { > // protected from non-object locals in calling methods > if (this != DEAD_END) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- long mask; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >- this.nullAssignmentStatusBit1 |= (mask = 1L << position); >- this.nullAssignmentValueBit2 |= mask; // set non null >- this.nullAssignmentStatusBit2 &= ~mask; // clear protection >- this.nullAssignmentValueBit1 &= ~mask; // clear null >- if (coverageTestFlag && coverageTestId == 29) { >- this.nullAssignmentStatusBit1 = 0; >- } >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- this.extra[2][vectorIndex] |= >- (mask = 1L << (position % BitCacheSize)); >- this.extra[5][vectorIndex] |= mask; >- this.extra[3][vectorIndex] &= ~mask; >- this.extra[4][vectorIndex] &= ~mask; >- if (coverageTestFlag && coverageTestId == 30) { >- this.extra[5][vectorIndex] = ~0; >- } >- } >+ this.tagBits |= NULL_FLAG_MASK; >+ long mask; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // set assigned non null >+ this.nullBit1 |= (mask = 1L << position); >+ this.nullBit3 |= mask; >+ // clear others >+ this.nullBit2 &= (mask = ~mask); >+ this.nullBit4 &= mask; >+ if (coverageTestFlag && coverageTestId == 22) { >+ this.nullBit1 = 0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex ; >+ this.extra[2][vectorIndex = (position / BitCacheSize) - 1] >+ |= (mask = 1L << (position % BitCacheSize)); >+ this.extra[4][vectorIndex] |= mask; >+ this.extra[3][vectorIndex] &= (mask = ~mask); >+ this.extra[5][vectorIndex] &= mask; >+ if (coverageTestFlag && coverageTestId == 23) { >+ this.extra[2][vectorIndex] = 0; >+ } >+ } > } > } > > public void markAsDefinitelyNull(LocalVariableBinding local) { > // protected from non-object locals in calling methods > if (this != DEAD_END) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- long mask; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >- this.nullAssignmentStatusBit1 |= (mask = 1L << position); // set assignment >- this.nullAssignmentStatusBit2 &= ~mask; // clear protection >- this.nullAssignmentValueBit1 |= mask; // set null >- this.nullAssignmentValueBit2 &= ~mask; // clear non null >- if (coverageTestFlag && coverageTestId == 31) { >- this.nullAssignmentValueBit2 = ~0; >- } >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- this.extra[2][vectorIndex] |= >- (mask = 1L << (position % BitCacheSize)); >- this.extra[3][vectorIndex] &= ~mask; >- this.extra[4][vectorIndex] |= mask; >- this.extra[5][vectorIndex] &= ~mask; >- if (coverageTestFlag && coverageTestId == 32) { >- this.extra[5][vectorIndex] = ~0; >- } >- } >+ this.tagBits |= NULL_FLAG_MASK; >+ long mask; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // mark assigned null >+ this.nullBit1 |= (mask = 1L << position); >+ this.nullBit2 |= mask; >+ // clear others >+ this.nullBit3 &= (mask = ~mask); >+ this.nullBit4 &= mask; >+ if (coverageTestFlag && coverageTestId == 24) { >+ this.nullBit4 = ~0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex ; >+ this.extra[2][vectorIndex = (position / BitCacheSize) - 1] >+ |= (mask = 1L << (position % BitCacheSize)); >+ this.extra[3][vectorIndex] |= mask; >+ this.extra[4][vectorIndex] &= (mask = ~mask); >+ this.extra[5][vectorIndex] &= mask; >+ if (coverageTestFlag && coverageTestId == 25) { >+ this.extra[5][vectorIndex] = ~0; >+ } >+ } > } > } > >@@ -1231,27 +1164,26 @@ > // position is zero-based > if ((position = local.id + this.maxFieldCount) < BitCacheSize) { > // use bits >- this.nullAssignmentValueBit1 |= (mask = 1L << position); >- this.nullAssignmentValueBit2 |= mask; >- // set unknown >- this.nullAssignmentStatusBit1 |= mask; >- // set assignment >- this.nullAssignmentStatusBit2 &= ~mask; >- // clear protection >- if (coverageTestFlag && coverageTestId == 33) { >- this.nullAssignmentValueBit2 = ~0; >+ // mark assigned null >+ this.nullBit1 |= (mask = 1L << position); >+ this.nullBit4 |= mask; >+ // clear others >+ this.nullBit2 &= (mask = ~mask); >+ this.nullBit3 &= mask; >+ if (coverageTestFlag && coverageTestId == 26) { >+ this.nullBit4 = 0; > } > } > else { > // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- this.extra[4][vectorIndex] |= >- (mask = 1L << (position % BitCacheSize)); >+ int vectorIndex ; >+ this.extra[2][vectorIndex = (position / BitCacheSize) - 1] >+ |= (mask = 1L << (position % BitCacheSize)); > this.extra[5][vectorIndex] |= mask; >- this.extra[2][vectorIndex] |= mask; >- this.extra[3][vectorIndex] &= ~mask; >- if (coverageTestFlag && coverageTestId == 34) { >- this.extra[5][vectorIndex] = ~0; >+ this.extra[3][vectorIndex] &= (mask = ~mask); >+ this.extra[4][vectorIndex] &= mask; >+ if (coverageTestFlag && coverageTestId == 27) { >+ this.extra[5][vectorIndex] = 0; > } > } > } >@@ -1259,15 +1191,14 @@ > > public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { > if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) { >- if (coverageTestFlag && coverageTestId == 35) { >- throw new AssertionFailedException("COVERAGE 35"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 28) { >+ throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$ > } >- // DEAD_END + unreachable other -> other > return this; > } > if ((this.tagBits & UNREACHABLE) != 0) { >- if (coverageTestFlag && coverageTestId == 36) { >- throw new AssertionFailedException("COVERAGE 36"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 29) { >+ throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$ > } > return (UnconditionalFlowInfo) otherInits.copy(); // make sure otherInits won't be affected > } >@@ -1278,69 +1209,75 @@ > this.potentialInits |= otherInits.potentialInits; > > // null combinations >- boolean otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0, >- thisHasNulls = false; >- long a1, a2, na2, a3, na3, a4, na4, b1, nb1, b2, nb2, b3, nb3, b4, nb4; >- if (otherHasNulls) { >- this.nullAssignmentStatusBit1 = >- (a1 = this.nullAssignmentStatusBit1) & >- (b1 = otherInits.nullAssignmentStatusBit1) & ( >- (nb4 = ~(b4 = otherInits.nullAssignmentValueBit2)) & >- ((b2 = otherInits.nullAssignmentStatusBit2) & >- (nb3 = ~(b3 = otherInits.nullAssignmentValueBit1)) & >- (na3 = ~(a3 = this.nullAssignmentValueBit1)) & >- ((a2 = this.nullAssignmentStatusBit2) & >- (na4 = ~(a4 = this.nullAssignmentValueBit2)) | a4) | >- (na2 = ~a2) & a3 & na4 & (nb2 = ~b2) & b3 ) | >- b4 & (na3 & nb3 & (na4 & a2 | a4) | >- na2 & a4 & nb2)); >- this.nullAssignmentStatusBit2 = >- a2 & b2 & ~(a1 ^ b1) & (na3 & nb3 | na4 & nb4) | >- a1 & b1 & (a2 ^ b2) & na3 & nb3 | >- (a1 & na2 & (nb1 = ~b1) & b2 | ~a1 & a2 & b1 & nb2) & na4 & nb4; >- this.nullAssignmentValueBit1 = >- b1 & nb2 & nb4 | >- ~a1 & (a3 | >- a2 & na3 & (b1 | nb2)) | >- (a1 | na2) & nb1 & b2 & nb3 | >- nb1 & b3 | >- a1 & na2 & (na4 | >- b1 & nb2 & (a3 | b3)); >- this.nullAssignmentValueBit2 = >- a4 | b4; >- >- // WORK recode if tests succeed >- this.nullAssignmentValueBit1 &= >- ~(a1 & na2 & na3 & a4 & nb1 & b2 & nb3 & nb4 >- | ~a1 & a2 & na3 & na4 & b1 & nb2 & nb3 & b4); >- >- if (coverageTestFlag && coverageTestId == 37) { >- this.nullAssignmentValueBit2 = ~0; >- } >+ boolean >+ thisHasNulls = (this.tagBits & NULL_FLAG_MASK) != 0, >+ otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0, >+ thisHadNulls = thisHasNulls; >+ long >+ a1, a2, a3, a4, >+ na1, na2, na3, na4, >+ nb1, nb2, nb3, nb4, >+ b1, b2, b3, b4; >+ 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.nullBit4 = na3 & (nb1 & nb3 & b4 >+ | b1 & (nb2 & nb3 | a4 & b2 & nb4) >+ | na1 & a4 & (nb3 | b1 & b2)) >+ | a3 & a4 & (b3 & b4 | b1 & nb2) >+ | 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); >+ if (coverageTestFlag && coverageTestId == 30) { >+ this.nullBit4 = ~0; >+ } >+ } else { // other has no null info >+ a1 = this.nullBit1; >+ this.nullBit1 = 0; >+ this.nullBit2 = (a2 = this.nullBit2) & (na3 = ~(a3 = this.nullBit3) | (na1 = ~a1)); >+ this.nullBit3 = a3 & ((na2 = ~a2) & (a4 = this.nullBit4) | na1) | a1 & na2 & ~a4; >+ this.nullBit4 = (na3 | na2) & na1 & a4 | a1 & na3 & na2; >+ if (coverageTestFlag && coverageTestId == 31) { >+ this.nullBit4 = ~0; >+ } >+ } >+ } else if (otherHasNulls) { // only other had nulls >+ this.nullBit1 = 0; >+ this.nullBit2 = (b2 = otherInits.nullBit2) & (nb3 = ~(b3 = otherInits.nullBit3) | (nb1 = ~(b1 = otherInits.nullBit1))); >+ this.nullBit3 = b3 & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1) | b1 & nb2 & ~b4; >+ this.nullBit4 = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2; >+ if (coverageTestFlag && coverageTestId == 32) { >+ this.nullBit4 = ~0; >+ } >+ thisHasNulls = >+ // redundant with the three following ones >+ this.nullBit2 != 0 || >+ this.nullBit3 != 0 || >+ this.nullBit4 != 0; > } >- else { >- // tune potentials >- this.nullAssignmentValueBit1 = >- ~(~this.nullAssignmentStatusBit1 & >- ~this.nullAssignmentStatusBit2 & >- ~this.nullAssignmentValueBit1) & >- ~(this.nullAssignmentStatusBit1 & >- (this.nullAssignmentStatusBit2 | this.nullAssignmentValueBit2)); >- // reset assignment and protected >- this.nullAssignmentStatusBit1 = >- this.nullAssignmentStatusBit2 = 0; >- if (coverageTestFlag && coverageTestId == 38) { >- this.nullAssignmentValueBit2 = ~0; >- } >- } >- thisHasNulls = this.nullAssignmentStatusBit1 != 0 || >- this.nullAssignmentStatusBit2 != 0 || >- this.nullAssignmentValueBit1 != 0 || >- this.nullAssignmentValueBit2 != 0; > > // treating extra storage > if (this.extra != null || otherInits.extra != null) { > int mergeLimit = 0, copyLimit = 0, resetLimit = 0; >+ int i; > if (this.extra != null) { > if (otherInits.extra != null) { > // both sides have extra storage >@@ -1354,23 +1291,23 @@ > } > mergeLimit = length; > copyLimit = otherLength; >- if (coverageTestFlag && coverageTestId == 39) { >- throw new AssertionFailedException("COVERAGE 39"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 33) { >+ throw new AssertionFailedException("COVERAGE 33"); //$NON-NLS-1$ > } > } > else { > // current storage is longer > mergeLimit = otherLength; > resetLimit = length; >- if (coverageTestFlag && coverageTestId == 40) { >- throw new AssertionFailedException("COVERAGE 40"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 34) { >+ throw new AssertionFailedException("COVERAGE 34"); //$NON-NLS-1$ > } > } > } > else { > resetLimit = this.extra[0].length; >- if (coverageTestFlag && coverageTestId == 41) { >- throw new AssertionFailedException("COVERAGE 41"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 35) { >+ throw new AssertionFailedException("COVERAGE 35"); //$NON-NLS-1$ > } > } > } >@@ -1384,114 +1321,93 @@ > System.arraycopy(otherInits.extra[1], 0, > this.extra[1], 0, otherLength); > copyLimit = otherLength; >- if (coverageTestFlag && coverageTestId == 42) { >- throw new AssertionFailedException("COVERAGE 42"); //$NON-NLS-1$ >+ if (coverageTestFlag && coverageTestId == 36) { >+ throw new AssertionFailedException("COVERAGE 36"); //$NON-NLS-1$ > } > } >- int i; >- if (otherHasNulls) { >- for (i = 0; i < mergeLimit; i++) { >- this.extra[0][i] &= >- otherInits.extra[0][i]; >- this.extra[1][i] |= >- otherInits.extra[1][i]; >- this.extra[2][i] = >- (a1 = this.extra[2][i]) & >- (b1 = otherInits.extra[2][i]) & ( >- (nb4 = ~(b4 = otherInits.extra[5][i])) & >- ((b2 = otherInits.extra[3][i]) & >- (nb3 = ~(b3 = otherInits.extra[4][i])) & >- (na3 = ~(a3 = this.extra[4][i])) & >- ((a2 = this.extra[3][i]) & >- (na4 = ~(a4 = this.extra[5][i])) | a4) | >- (na2 = ~a2) & a3 & na4 & (nb2 = ~b2) & b3 ) | >- b4 & (na3 & nb3 & (na4 & a2 | a4) | >- na2 & a4 & nb2)); >- this.extra[3][i] = >- a2 & b2 & ~(a1 ^ b1) & (na3 & nb3 | na4 & nb4) | >- a1 & b1 & (a2 ^ b2) & na3 & nb3 | >- (a1 & na2 & (nb1 = ~b1) & b2 | ~a1 & a2 & b1 & nb2) & na4 & nb4; >- this.extra[4][i] = >- b1 & nb2 & nb4 | >- ~a1 & (a3 | >- a2 & na3 & (b1 | nb2)) | >- (a1 | na2) & nb1 & b2 & nb3 | >- nb1 & b3 | >- a1 & na2 & (na4 | >- b1 & nb2 & (a3 | b3)); >- this.extra[5][i] = >- a4 | b4; >- >- // WORK recode if tests succeed >- this.extra[4][i] &= >- ~(a1 & na2 & na3 & a4 & nb1 & b2 & nb3 & nb4 >- | ~a1 & a2 & na3 & na4 & b1 & nb2 & nb3 & b4); >- >- thisHasNulls = thisHasNulls || >- this.extra[5][i] != 0 || >- this.extra[2][i] != 0 || >- this.extra[3][i] != 0 || >- this.extra[4][i] != 0; >- if (coverageTestFlag && coverageTestId == 43) { >- this.extra[5][i] = ~0; >- } >- } >+ // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][i]/g >+ // manage definite assignment >+ for (i = 0; i < mergeLimit; i++) { >+ this.extra[0][i] &= otherInits.extra[0][i]; >+ this.extra[1][i] |= otherInits.extra[1][i]; > } >- else { >- for (i = 0; i < mergeLimit; i++) { >- this.extra[0][i] &= >- otherInits.extra[0][i]; >- this.extra[1][i] |= >- otherInits.extra[1][i]; >- this.extra[4][i] = >- ~(~this.extra[2][i] & >- ~this.extra[3][i] & >- ~this.extra[4][i]) & >- ~(this.extra[2][i] & >- (this.extra[3][i] | >- this.extra[5][i])); >- this.extra[2][i] = >- this.extra[3][i] = 0; >- thisHasNulls = thisHasNulls || >- this.extra[4][i] != 0 || >- this.extra[5][i] != 0; >- if (coverageTestFlag && coverageTestId == 44) { >- this.extra[5][i] = ~0; >- } >+ for (; i < copyLimit; i++) { >+ this.extra[1][i] = otherInits.extra[1][i]; >+ } >+ for (; i < resetLimit; i++) { >+ this.extra[0][i] = 0; >+ } >+ // refine null bits requirements >+ if (!otherHasNulls) { >+ if (resetLimit < mergeLimit) { >+ resetLimit = mergeLimit; >+ } >+ copyLimit = 0; // no need to carry inexisting nulls >+ mergeLimit = 0; >+ } >+ if (!thisHadNulls) { >+ resetLimit = 0; // no need to reset anything >+ } >+ // 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[4 + 1][i] = na3 & (nb1 & nb3 & b4 >+ | b1 & (nb2 & nb3 | a4 & b2 & nb4) >+ | na1 & a4 & (nb3 | b1 & b2)) >+ | a3 & a4 & (b3 & b4 | b1 & nb2) >+ | 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); >+ thisHasNulls = thisHasNulls || >+ this.extra[3][i] != 0 || >+ this.extra[4][i] != 0 || >+ this.extra[5][i] != 0 ; >+ if (coverageTestFlag && coverageTestId == 37) { >+ this.extra[5][i] = ~0; > } > } > for (; i < copyLimit; i++) { >- this.extra[1][i] = otherInits.extra[1][i]; >- this.extra[4][i] = >- ~(~otherInits.extra[2][i] & >- ~otherInits.extra[3][i] & >- ~otherInits.extra[4][i]) & >- ~(otherInits.extra[2][i] & >- (otherInits.extra[3][i] | >- otherInits.extra[5][i])); >- this.extra[5][i] = otherInits.extra[5][i]; >+ this.extra[1 + 1][i] = 0; >+ this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i]))); >+ this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4; >+ this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2; > thisHasNulls = thisHasNulls || >+ this.extra[3][i] != 0 || > this.extra[4][i] != 0 || > this.extra[5][i] != 0; >- if (coverageTestFlag && coverageTestId == 45) { >+ if (coverageTestFlag && coverageTestId == 38) { > this.extra[5][i] = ~0; > } > } > for (; i < resetLimit; i++) { >- this.extra[4][i] = >- ~(~this.extra[2][i] & >- ~this.extra[3][i] & >- ~this.extra[4][i]) & >- ~(this.extra[2][i] & >- (this.extra[3][i] | >- this.extra[5][i])); >- this.extra[0][i] = >- this.extra[2][i] = >- this.extra[3][i] = 0; >+ a1 = this.extra[1 + 1][i]; >+ this.extra[1 + 1][i] = 0; >+ this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1)); >+ this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4; >+ this.extra[4 + 1][i] = (na3 | na2) & na1 & a4 | a1 & na3 & na2; > thisHasNulls = thisHasNulls || >+ this.extra[3][i] != 0 || > this.extra[4][i] != 0 || > this.extra[5][i] != 0; >- if (coverageTestFlag && coverageTestId == 46) { >+ if (coverageTestFlag && coverageTestId == 39) { > this.extra[5][i] = ~0; > } > } >@@ -1577,19 +1493,15 @@ > return "FlowInfo<def: " + this.definiteInits //$NON-NLS-1$ > +", pot: " + this.potentialInits //$NON-NLS-1$ > + ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$ >- +", nullS1: " + this.nullAssignmentStatusBit1 //$NON-NLS-1$ >- +", nullS2: " + this.nullAssignmentStatusBit2 //$NON-NLS-1$ >- +", nullV1: " + this.nullAssignmentValueBit1 //$NON-NLS-1$ >- +", nullV2: " + this.nullAssignmentValueBit2 //$NON-NLS-1$ >+ +", null: " + this.nullBit1 //$NON-NLS-1$ >+ + this.nullBit2 + this.nullBit3 + this.nullBit4 > +">"; //$NON-NLS-1$ > } > else { > String def = "FlowInfo<def:[" + this.definiteInits, //$NON-NLS-1$ > pot = "], pot:[" + this.potentialInits, //$NON-NLS-1$ >- nullS1 = ", nullS1:[" + this.nullAssignmentStatusBit1, //$NON-NLS-1$ >- nullS2 = "], nullS2:[" + this.nullAssignmentStatusBit2, //$NON-NLS-1$ >- nullV1 = "], nullV1:[" + this.nullAssignmentValueBit1, //$NON-NLS-1$ >- nullV2 = "], nullV2:[" + this.nullAssignmentValueBit2; //$NON-NLS-1$ >+ nullS = ", null:[" + this.nullBit1 //$NON-NLS-1$ >+ + this.nullBit2 + this.nullBit3 + this.nullBit4; > int i, ceil; > for (i = 0, ceil = this.extra[0].length > 3 ? > 3 : >@@ -1597,22 +1509,17 @@ > i < ceil; i++) { > def += "," + this.extra[0][i]; //$NON-NLS-1$ > pot += "," + this.extra[1][i]; //$NON-NLS-1$ >- nullS1 += "," + this.extra[2][i]; //$NON-NLS-1$ >- nullS2 += "," + this.extra[3][i]; //$NON-NLS-1$ >- nullV1 += "," + this.extra[4][i]; //$NON-NLS-1$ >- nullV2 += "," + this.extra[5][i]; //$NON-NLS-1$ >+ nullS += "," + this.extra[2][i] //$NON-NLS-1$ >+ + this.extra[3][i] + this.extra[4][i] + this.extra[5][i]; > } > if (ceil < this.extra[0].length) { > def += ",..."; //$NON-NLS-1$ > pot += ",..."; //$NON-NLS-1$ >- nullS1 += ",..."; //$NON-NLS-1$ >- nullS2 += ",..."; //$NON-NLS-1$ >- nullV1 += ",..."; //$NON-NLS-1$ >- nullV2 += ",..."; //$NON-NLS-1$ >+ nullS += ",..."; //$NON-NLS-1$ > } > return def + pot > + "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$ >- + nullS1 + nullS2 + nullV1 + nullV2 >+ + nullS > + "]>"; //$NON-NLS-1$ > } > } >@@ -1659,10 +1566,10 @@ > long mask; > copy.definiteInits = this.definiteInits & (mask = ~((1L << limit)-1)); > copy.potentialInits = this.potentialInits & mask; >- copy.nullAssignmentStatusBit1 = this.nullAssignmentStatusBit1 & mask; >- copy.nullAssignmentStatusBit2 = this.nullAssignmentStatusBit2 & mask; >- copy.nullAssignmentValueBit1 = this.nullAssignmentValueBit1 & mask; >- copy.nullAssignmentValueBit2 = this.nullAssignmentValueBit2 & mask; >+ copy.nullBit1 = this.nullBit1 & mask; >+ copy.nullBit2 = this.nullBit2 & mask; >+ copy.nullBit3 = this.nullBit3 & mask; >+ copy.nullBit4 = this.nullBit4 & mask; > } > // use extra vector > if (this.extra == null) { >Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java,v >retrieving revision 1.31 >diff -u -r1.31 FlowInfo.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java 28 Mar 2006 20:32:37 -0000 1.31 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java 21 Apr 2006 14:13:19 -0000 >@@ -141,6 +141,15 @@ > > /** > * Check status of potential null assignment for a local. Return true if there >+ * is a reasonable expectation that the variable be non null at this point. >+ * @param local LocalVariableBinding - the binding for the checked local >+ * @return true if there is a reasonable expectation that local be non null at >+ * this point >+ */ >+public abstract boolean isPotentiallyNonNull(LocalVariableBinding local); >+ >+/** >+ * Check status of potential null assignment for a local. Return true if there > * is a reasonable expectation that the variable be null at this point. This > * includes the protected null case, so as to augment diagnostics, but does not > * really check that someone deliberately assigned to null on any specific >@@ -184,7 +193,7 @@ > * @param local the checked local variable > */ > abstract public void markAsComparedEqualToNull(LocalVariableBinding local); >- >+ > /** > * Record a field got definitely assigned. > */ >Index: compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java,v >retrieving revision 1.25 >diff -u -r1.25 ConditionalFlowInfo.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java 8 Mar 2006 09:54:00 -0000 1.25 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java 21 Apr 2006 14:13:19 -0000 >@@ -102,6 +102,11 @@ > || initsWhenFalse.isPotentiallyAssigned(local); > } > >+public boolean isPotentiallyNonNull(LocalVariableBinding local) { >+ return initsWhenTrue.isPotentiallyNonNull(local) >+ || initsWhenFalse.isPotentiallyNonNull(local); >+} >+ > public boolean isPotentiallyNull(LocalVariableBinding local) { > return initsWhenTrue.isPotentiallyNull(local) > || initsWhenFalse.isPotentiallyNull(local); >Index: compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java,v >retrieving revision 1.33 >diff -u -r1.33 LoopingFlowContext.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java 28 Mar 2006 20:32:37 -0000 1.33 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java 21 Apr 2006 14:13:19 -0000 >@@ -121,12 +121,25 @@ > Expression expression = this.nullReferences[i]; > // final local variable > switch (this.nullCheckTypes[i]) { >+ case CAN_ONLY_NON_NULL : >+ if (flowInfo.isDefinitelyNonNull(local)) { >+ this.nullReferences[i] = null; >+ scope.problemReporter().localVariableCannotBeNull(local, expression); >+ continue; >+ } >+ break; > case CAN_ONLY_NULL_NON_NULL : > if (flowInfo.isDefinitelyNonNull(local)) { > this.nullReferences[i] = null; > scope.problemReporter().localVariableCannotBeNull(local, expression); > continue; > } >+ if (flowInfo.isDefinitelyNull(local)) { >+ this.nullReferences[i] = null; >+ scope.problemReporter().localVariableCanOnlyBeNull(local, expression); >+ continue; >+ } >+ break; > case CAN_ONLY_NULL : > if (flowInfo.isDefinitelyNull(local)) { > this.nullReferences[i] = null; >@@ -311,11 +324,8 @@ > } > switch (checkType) { > case CAN_ONLY_NULL_NON_NULL : >- case CAN_ONLY_NULL: > if (flowInfo.isDefinitelyNonNull(local)) { >- if (checkType == CAN_ONLY_NULL_NON_NULL) { >- scope.problemReporter().localVariableCannotBeNull(local, reference); >- } >+ scope.problemReporter().localVariableCannotBeNull(local, reference); > return; > } > if (flowInfo.isDefinitelyNull(local)) { >@@ -325,6 +335,21 @@ > if (flowInfo.isPotentiallyUnknown(local)) { > return; > } >+ if (flowInfo.isPotentiallyNonNull(local)) { >+ recordNullReference(local, reference,CAN_ONLY_NON_NULL); >+ } else { >+ recordNullReference(local, reference, checkType); >+ } >+ return; >+ case CAN_ONLY_NULL: >+ if (flowInfo.isPotentiallyNonNull(local) >+ || flowInfo.isPotentiallyUnknown(local)) { >+ return; >+ } >+ if (flowInfo.isDefinitelyNull(local)) { >+ scope.problemReporter().localVariableCanOnlyBeNull(local, reference); >+ return; >+ } > recordNullReference(local, reference, checkType); > return; > case MAY_NULL : >Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java,v >retrieving revision 1.51 >diff -u -r1.51 FlowContext.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 28 Mar 2006 20:32:37 -0000 1.51 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 21 Apr 2006 14:13:19 -0000 >@@ -36,13 +36,6 @@ > > // preempt marks looping contexts > public final static FlowContext NotContinuableContext = new FlowContext(null, null); >- public static final int >- CAN_ONLY_NULL_NON_NULL = 20, >- // check against null and non null, with definite values -- comparisons >- CAN_ONLY_NULL = 21, >- // check against null, with definite values -- assignment to null >- MAY_NULL = 22; >- // check against null, with potential values -- NPE guard > public ASTNode associatedNode; > public FlowContext parent; > public NullInfoRegistry initsOnFinally; >@@ -468,6 +461,17 @@ > } > } > >+public static final int >+ CAN_ONLY_NULL_NON_NULL = 20, >+ // check against null and non null, with definite values -- comparisons >+ CAN_ONLY_NULL = 21, >+ // check against null, with definite values -- assignment to null >+ MAY_NULL = 22, >+ // check against null, with potential values -- NPE guard >+ CAN_ONLY_NON_NULL = 23; >+ // subcase of CAN_ONLY_NULL_NON_NULL, in which we know that the local >+ // may be non null >+ > /** > * Record a null reference for use by deferred checks. Only looping or > * finally contexts really record that information. The context may >Index: compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java,v >retrieving revision 1.3 >diff -u -r1.3 NullInfoRegistry.java >--- compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java 16 Mar 2006 11:59:44 -0000 1.3 >+++ compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java 21 Apr 2006 14:13:20 -0000 >@@ -24,15 +24,8 @@ > * flow info presented in input of finally blocks. > */ > public class NullInfoRegistry extends UnconditionalFlowInfo { >- // encoding of null status at this level: >-// public long nullAssignmentStatusBit1; >- // assigned null >-// public long nullAssignmentStatusBit2; >- // assigned non null >-// public long nullAssignmentValueBit1; >- // assigned unknown >-// public long nullAssignmentValueBit2; >- // message send (no NPE) >+ // significant states at this level: >+ // def. non null, def. null, def. unknown, prot. non null > > // PREMATURE implement coverage and low level tests > >@@ -46,38 +39,32 @@ > */ > public NullInfoRegistry(UnconditionalFlowInfo upstream) { > if ((upstream.tagBits & NULL_FLAG_MASK) != 0) { >- long a1, a2, a3, b1nb2, b3, b4; >- a1 = this.nullAssignmentStatusBit1 = >- (b1nb2 = upstream.nullAssignmentStatusBit1 >- & ~upstream.nullAssignmentStatusBit2) >- & (b3 = upstream.nullAssignmentValueBit1) >- & ~(b4 = upstream.nullAssignmentValueBit2); >- a2 = this.nullAssignmentStatusBit2 = >- b1nb2 & ~b3 & b4; >- a3 = this.nullAssignmentValueBit1 = >- b1nb2 & b3 & b4; >- if ((a1 | a2 | a3) != 0) { >+ long u1, u2, u3, u4, nu2, nu3, nu4; >+ this.nullBit2 = (u1 = upstream.nullBit1) >+ & (u2 = upstream.nullBit2) >+ & (nu3 = ~(u3 = upstream.nullBit3)) >+ & (nu4 = ~(u4 = upstream.nullBit4)); >+ this.nullBit3 = u1 & (nu2 = ~u2) & u3 & nu4; >+ this.nullBit4 = u1 & nu2 &nu3 & u4; >+ if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { > this.tagBits |= NULL_FLAG_MASK; > } > if (upstream.extra != null) { > this.extra = new long[extraLength][]; >- int length= upstream.extra[2].length; >+ int length = upstream.extra[2].length; > for (int i = 2; i < extraLength; i++) { > this.extra[i] = new long[length]; > } > for (int i = 0; i < length; i++) { >- a1 = this.extra[2][i] = >- (b1nb2 = upstream.extra[2][i] >- & ~upstream.extra[3][i]) >- & (b3 = upstream.extra[4][i]) >- & ~(b4 = upstream.extra[5][i]); >- a2 = this.extra[3][i] = >- b1nb2 & ~b3 & b4; >- a3 = this.extra[4][i] = >- b1nb2 & b3 & b4; >- if ((a1 | a2 | a3) != 0) { >- this.tagBits |= NULL_FLAG_MASK; >- } >+ this.extra[2 + 1][i] = (u1 = upstream.extra[1 + 1][i]) >+ & (u2 = upstream.extra[2 + 1][i]) >+ & (nu3 = ~(u3 = upstream.extra[3 + 1][i])) >+ & (nu4 = ~(u4 = upstream.extra[4 + 1][i])); >+ this.extra[3 + 1][i] = u1 & (nu2 = ~u2) & u3 & nu4; >+ this.extra[4 + 1][i] = u1 & nu2 &nu3 & u4; >+ if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { >+ this.tagBits |= NULL_FLAG_MASK; >+ } > } > } > } >@@ -94,10 +81,10 @@ > return this; > } > this.tagBits |= NULL_FLAG_MASK; >- this.nullAssignmentStatusBit1 |= other.nullAssignmentStatusBit1; >- this.nullAssignmentStatusBit2 |= other.nullAssignmentStatusBit2; >- this.nullAssignmentValueBit1 |= other.nullAssignmentValueBit1; >- this.nullAssignmentValueBit2 |= other.nullAssignmentValueBit2; >+ this.nullBit1 |= other.nullBit1; >+ this.nullBit2 |= other.nullBit2; >+ this.nullBit3 |= other.nullBit3; >+ this.nullBit4 |= other.nullBit4; > if (other.extra != null) { > if (this.extra == null) { > this.extra = new long[extraLength][]; >@@ -128,142 +115,167 @@ > } > > public void markAsComparedEqualToNonNull(LocalVariableBinding local) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { >- // use bits >- this.nullAssignmentValueBit2 |= (1L << position); >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- if (this.extra == null) { >- int length = vectorIndex + 1; >- this.extra = new long[extraLength][]; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- this.extra[j] = new long[length]; >- } >- } >- else { >- int oldLength; >- if (vectorIndex >= (oldLength = this.extra[2].length)) { >- int newLength = vectorIndex + 1; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- (this.extra[j] = new long[newLength]), 0, >- oldLength); >+ // protected from non-object locals in calling methods >+ if (this != DEAD_END) { >+ this.tagBits |= NULL_FLAG_MASK; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // set protected non null >+ this.nullBit1 |= (1L << position); >+ if (coverageTestFlag && coverageTestId == 290) { >+ this.nullBit1 = 0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex = (position / BitCacheSize) - 1; >+ if (this.extra == null) { >+ int length = vectorIndex + 1; >+ this.extra = new long[extraLength][]; >+ for (int j = 2; j < extraLength; j++) { >+ this.extra[j] = new long[length]; >+ } >+ } >+ else { >+ int oldLength; // might need to grow the arrays >+ if (vectorIndex >= (oldLength = this.extra[2].length)) { >+ for (int j = 2; j < extraLength; j++) { >+ System.arraycopy(this.extra[j], 0, >+ (this.extra[j] = new long[vectorIndex + 1]), 0, >+ oldLength); >+ } > } > } >- } >- this.extra[5][vectorIndex] |= (1L << (position % BitCacheSize)); >+ this.extra[2][vectorIndex] |= (1L << (position % BitCacheSize)); >+ if (coverageTestFlag && coverageTestId == 300) { >+ this.extra[5][vectorIndex] = ~0; >+ } >+ } > } > } > > public void markAsDefinitelyNonNull(LocalVariableBinding local) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { >- // use bits >- this.nullAssignmentStatusBit2 |= (1L << position); >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- if (this.extra == null) { >- int length = vectorIndex + 1; >- this.extra = new long[extraLength][]; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- this.extra[j] = new long[length]; >- } >- } >- else { >- int oldLength; >- if (vectorIndex >= (oldLength = this.extra[2].length)) { >- int newLength = vectorIndex + 1; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- (this.extra[j] = new long[newLength]), 0, >- oldLength); >+ // protected from non-object locals in calling methods >+ if (this != DEAD_END) { >+ this.tagBits |= NULL_FLAG_MASK; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // set assigned non null >+ this.nullBit3 |= (1L << position); >+ if (coverageTestFlag && coverageTestId == 290) { >+ this.nullBit1 = 0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex = (position / BitCacheSize) - 1; >+ if (this.extra == null) { >+ int length = vectorIndex + 1; >+ this.extra = new long[extraLength][]; >+ for (int j = 2; j < extraLength; j++) { >+ this.extra[j] = new long[length]; >+ } >+ } >+ else { >+ int oldLength; // might need to grow the arrays >+ if (vectorIndex >= (oldLength = this.extra[2].length)) { >+ for (int j = 2; j < extraLength; j++) { >+ System.arraycopy(this.extra[j], 0, >+ (this.extra[j] = new long[vectorIndex + 1]), 0, >+ oldLength); >+ } > } > } >- } >- this.extra[3][vectorIndex] |= (1L << (position % BitCacheSize)); >+ this.extra[4][vectorIndex] |= (1L << (position % BitCacheSize)); >+ if (coverageTestFlag && coverageTestId == 300) { >+ this.extra[5][vectorIndex] = ~0; >+ } >+ } > } > } >- >+// PREMATURE consider ignoring extra 0 to 2 included - means a1 should not be used either >+// PREMATURE project protected non null onto something else > public void markAsDefinitelyNull(LocalVariableBinding local) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { >- // use bits >- this.nullAssignmentStatusBit1 |= (1L << position); >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- if (this.extra == null) { >- int length = vectorIndex + 1; >- this.extra = new long[extraLength][]; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- this.extra[j] = new long[length]; >- } >- } >- else { >- int oldLength; >- if (vectorIndex >= (oldLength = this.extra[2].length)) { >- int newLength = vectorIndex + 1; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- (this.extra[j] = new long[newLength]), 0, >- oldLength); >+ // protected from non-object locals in calling methods >+ if (this != DEAD_END) { >+ this.tagBits |= NULL_FLAG_MASK; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // set assigned null >+ this.nullBit2 |= (1L << position); >+ if (coverageTestFlag && coverageTestId == 290) { >+ this.nullBit1 = 0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex = (position / BitCacheSize) - 1; >+ if (this.extra == null) { >+ int length = vectorIndex + 1; >+ this.extra = new long[extraLength][]; >+ for (int j = 2; j < extraLength; j++) { >+ this.extra[j] = new long[length]; >+ } >+ } >+ else { >+ int oldLength; // might need to grow the arrays >+ if (vectorIndex >= (oldLength = this.extra[2].length)) { >+ for (int j = 2; j < extraLength; j++) { >+ System.arraycopy(this.extra[j], 0, >+ (this.extra[j] = new long[vectorIndex + 1]), 0, >+ oldLength); >+ } > } > } >- } >- this.extra[2][vectorIndex] |= (1L << (position % BitCacheSize)); >+ this.extra[3][vectorIndex] |= (1L << (position % BitCacheSize)); >+ if (coverageTestFlag && coverageTestId == 300) { >+ this.extra[5][vectorIndex] = ~0; >+ } >+ } > } > } > > public void markAsDefinitelyUnknown(LocalVariableBinding local) { >- this.tagBits |= NULL_FLAG_MASK; >- int position; >- // position is zero-based >- if ((position = local.id + this.maxFieldCount) < BitCacheSize) { >- // use bits >- this.nullAssignmentValueBit1 |= (1L << position); >- } >- else { >- // use extra vector >- int vectorIndex = (position / BitCacheSize) - 1; >- if (this.extra == null) { >- int length = vectorIndex + 1; >- this.extra = new long[extraLength][]; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- this.extra[j] = new long[length]; >- } >- } >- else { >- int oldLength; >- if (vectorIndex >= (oldLength = this.extra[2].length)) { >- int newLength = vectorIndex + 1; >- for (int j = 2 /* do not care about non null info */; >- j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- (this.extra[j] = new long[newLength]), 0, >- oldLength); >+ // protected from non-object locals in calling methods >+ if (this != DEAD_END) { >+ this.tagBits |= NULL_FLAG_MASK; >+ int position; >+ // position is zero-based >+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits >+ // set assigned unknown >+ this.nullBit4 |= (1L << position); >+ if (coverageTestFlag && coverageTestId == 290) { >+ this.nullBit1 = 0; >+ } >+ } >+ else { >+ // use extra vector >+ int vectorIndex = (position / BitCacheSize) - 1; >+ if (this.extra == null) { >+ int length = vectorIndex + 1; >+ this.extra = new long[extraLength][]; >+ for (int j = 2; j < extraLength; j++) { >+ this.extra[j] = new long[length]; >+ } >+ } >+ else { >+ int oldLength; // might need to grow the arrays >+ if (vectorIndex >= (oldLength = this.extra[2].length)) { >+ for (int j = 2; j < extraLength; j++) { >+ System.arraycopy(this.extra[j], 0, >+ (this.extra[j] = new long[vectorIndex + 1]), 0, >+ oldLength); >+ } > } > } >- } >- this.extra[4][vectorIndex] |= (1L << (position % BitCacheSize)); >+ this.extra[5][vectorIndex] |= (1L << (position % BitCacheSize)); >+ if (coverageTestFlag && coverageTestId == 300) { >+ this.extra[5][vectorIndex] = ~0; >+ } >+ } > } > } > >@@ -281,58 +293,32 @@ > if ((this.tagBits & NULL_FLAG_MASK) == 0) { > return flowInfo.unconditionalInits(); > } >-// // Reference implementation >-// UnconditionalFlowInfo source = flowInfo.unconditionalCopy(); >-// long mask; >-// // clear uncompatible protections >-// mask = source.nullAssignmentStatusBit1 & source.nullAssignmentStatusBit2 >-// // prot. non null >-// & (this.nullAssignmentStatusBit1 | this.nullAssignmentValueBit1); >-// // null or unknown >-// source.nullAssignmentStatusBit1 &= ~mask; >-// source.nullAssignmentStatusBit2 &= ~mask; >-// mask = ~source.nullAssignmentStatusBit1 & source.nullAssignmentStatusBit2 >-// // prot. null >-// & (this.nullAssignmentStatusBit2 | this.nullAssignmentValueBit1 >-// | this.nullAssignmentValueBit2); >-// // non null or unknown >-// source.nullAssignmentStatusBit2 &= ~mask; >-// // clear uncompatible assignments >-// mask = source.nullAssignmentStatusBit1 & ~source.nullAssignmentStatusBit2 >-// & (source.nullAssignmentValueBit1 & ~source.nullAssignmentValueBit2 >-// & (this.nullAssignmentStatusBit2 | this.nullAssignmentValueBit1 >-// | this.nullAssignmentValueBit2) >-// | ~source.nullAssignmentValueBit1 & source.nullAssignmentValueBit2 >-// & (this.nullAssignmentStatusBit1 | this.nullAssignmentValueBit1) >-// | source.nullAssignmentValueBit1 & source.nullAssignmentValueBit2 >-// & (this.nullAssignmentStatusBit1)); >-// source.nullAssignmentStatusBit1 &= ~mask; >- long m1, m2, m3, a1, a2, a3, a4, s1, s2, s3, s4; >+ long m, m1, nm1, m2, nm2, m3, a2, a3, a4, s1, s2, ns2, s3, ns3, s4, ns4; > boolean newCopy = false; > UnconditionalFlowInfo source = flowInfo.unconditionalInits(); >- // clear uncompatible protections >- m1 = (s1 = source.nullAssignmentStatusBit1) >- & (s2 = source.nullAssignmentStatusBit2) >+ // clear incompatible protections >+ m1 = (s1 = source.nullBit1) & (s3 = source.nullBit3) >+ & (s4 = source.nullBit4) > // prot. non null >- & ((a1 = this.nullAssignmentStatusBit1) >- | (a3 = this.nullAssignmentValueBit1)); >+ & ((a2 = this.nullBit2) | (a4 = this.nullBit4)); > // null or unknown >- m2 = ~s1 & s2 >+ m2 = s1 & (s2 = this.nullBit2) & (s3 ^ s4) > // prot. null >- & ((a2 = this.nullAssignmentStatusBit2) | a3 >- | (a4 = this.nullAssignmentValueBit2)); >+ & ((a3 = this.nullBit3) | a4); > // non null or unknown >- // clear uncompatible assignments >- m3 = s1 & ~s2 >- & ((s3 = source.nullAssignmentValueBit1) >- & ~(s4 = source.nullAssignmentValueBit2) >- & (a2 | a3 | a4) >- | s4 & (~s3 & a3 | a1)); >- if ((m1 | m2 | m3) != 0) { >+ // clear incompatible assignments >+ // PREMATURE check effect of protected non null (no NPE on call) >+ // TODO (maxime) code extensive implementation tests >+ m3 = s1 & (s2 & (ns3 = ~s3) & (ns4 = ~s4) & (a3 | a4) >+ | (ns2 = ~s2) & s3 & ns4 & (a2 | a4) >+ | ns2 & ns3 & s4 & (a2 | a3)); >+ if ((m = (m1 | m2 | m3)) != 0) { > newCopy = true; > source = source.unconditionalCopy(); >- source.nullAssignmentStatusBit1 &= ~(m1 | m3); >- source.nullAssignmentStatusBit2 &= ~(m1 | m2); >+ source.nullBit1 &= ~m; >+ source.nullBit2 &= (nm1 = ~m1) & ((nm2 = ~m2) | a4); >+ source.nullBit3 &= (nm1 | a2) & nm2; >+ source.nullBit4 &= nm1 & nm2; > } > if (this.extra != null && source.extra != null) { > int length = this.extra[2].length, sourceLength = source.extra[0].length; >@@ -340,29 +326,24 @@ > length = sourceLength; > } > for (int i = 0; i < length; i++) { >- // clear uncompatible protections >- m1 = (s1 = source.extra[2][i]) & (s2 = source.extra[3][i]) >- // prot. non null >- & ((a1 = this.extra[2][i]) | (a3 = this.extra[4][i])); >- // null or unknown >- m2 = ~s1 & s2 >- // prot. null >- & ((a2 = this.extra[3][i]) | a3 >- | (a4 = this.extra[5][i])); >- // non null or unknown >- // clear uncompatible assignments >- m3 = s1 & ~s2 >- & ((s3 = source.extra[4][i]) & ~(s4 = source.extra[5][i]) >- & (a2 | a3 | a4) >- | s4 & (~s3 & a3 | a1)); >- if ((m1 | m2 | m3) != 0) { >- if (!newCopy) { >- newCopy = true; >- source = source.unconditionalCopy(); >- } >- source.extra[2][i] &= ~(m1 | m3); >- source.extra[3][i] &= ~(m1 | m2); >- } >+ m1 = (s1 = source.extra[1 + 1][i]) & (s3 = source.extra[3 + 1][i]) >+ & (s4 = source.extra[4 + 1][i]) >+ & ((a2 = this.extra[2 + 1][i]) | (a4 = this.extra[4 + 1][i])); >+ m2 = s1 & (s2 = this.extra[2 + 1][i]) & (s3 ^ s4) >+ & ((a3 = this.extra[3 + 1][i]) | a4); >+ m3 = s1 & (s2 & (ns3 = ~s3) & (ns4 = ~s4) & (a3 | a4) >+ | (ns2 = ~s2) & s3 & ns4 & (a2 | a4) >+ | ns2 & ns3 & s4 & (a2 | a3)); >+ if ((m = (m1 | m2 | m3)) != 0) { >+ if (! newCopy) { >+ newCopy = true; >+ source = source.unconditionalCopy(); >+ } >+ source.extra[1 + 1][i] &= ~m; >+ source.extra[2 + 1][i] &= (nm1 = ~m1) & ((nm2 = ~m2) | a4); >+ source.extra[3 + 1][i] &= (nm1 | a2) & nm2; >+ source.extra[4 + 1][i] &= nm1 & nm2; >+ } > } > } > return source; >@@ -370,35 +351,25 @@ > > public String toString(){ > if (this.extra == null) { >- return "NullInfoRegistry<nullS1: " + this.nullAssignmentStatusBit1 //$NON-NLS-1$ >- +", nullS2: " + this.nullAssignmentStatusBit2 //$NON-NLS-1$ >- +", nullV1: " + this.nullAssignmentValueBit1 //$NON-NLS-1$ >- +", nullV2: " + this.nullAssignmentValueBit2 //$NON-NLS-1$ >- +">"; //$NON-NLS-1$ >+ return "NullInfoRegistry<" + this.nullBit1 //$NON-NLS-1$ >+ + this.nullBit2 + this.nullBit3 + this.nullBit4 >+ + ">"; //$NON-NLS-1$ > } > else { >- String nullS1 = "NullInfoRegistry<nullS1:[" + this.nullAssignmentStatusBit1, //$NON-NLS-1$ >- nullS2 = "], nullS2:[" + this.nullAssignmentStatusBit2, //$NON-NLS-1$ >- nullV1 = "], nullV1:[" + this.nullAssignmentValueBit1, //$NON-NLS-1$ >- nullV2 = "], nullV2:[" + this.nullAssignmentValueBit2; //$NON-NLS-1$ >- int i, ceil; >- for (i = 0, ceil = this.extra[0].length > 3 ? >- 3 : >- this.extra[0].length; >- i < ceil; i++) { >- nullS1 += "," + this.extra[2][i]; //$NON-NLS-1$ >- nullS2 += "," + this.extra[3][i]; //$NON-NLS-1$ >- nullV1 += "," + this.extra[4][i]; //$NON-NLS-1$ >- nullV2 += "," + this.extra[5][i]; //$NON-NLS-1$ >- } >- if (ceil < this.extra[0].length) { >- nullS1 += ",..."; //$NON-NLS-1$ >- nullS2 += ",..."; //$NON-NLS-1$ >- nullV1 += ",..."; //$NON-NLS-1$ >- nullV2 += ",..."; //$NON-NLS-1$ >- } >- return nullS1 + nullS2 + nullV1 + nullV2 >- + "]>"; //$NON-NLS-1$ >+ String nullS = "NullInfoRegistry<[" + this.nullBit1 //$NON-NLS-1$ >+ + this.nullBit2 + this.nullBit3 + this.nullBit4; >+ int i, ceil; >+ for (i = 0, ceil = this.extra[0].length > 3 ? >+ 3 : >+ this.extra[0].length; >+ i < ceil; i++) { >+ nullS += "," + this.extra[2][i] //$NON-NLS-1$ >+ + this.extra[3][i] + this.extra[4][i] + this.extra[5][i]; >+ } >+ if (ceil < this.extra[0].length) { >+ nullS += ",..."; //$NON-NLS-1$ >+ } >+ return nullS + "]>"; //$NON-NLS-1$ > } > } > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java,v >retrieving revision 1.64 >diff -u -r1.64 EqualExpression.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java 28 Mar 2006 20:29:56 -0000 1.64 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java 21 Apr 2006 14:13:19 -0000 >@@ -113,7 +113,8 @@ > } > if (result instanceof UnconditionalFlowInfo && > (result.tagBits & FlowInfo.UNREACHABLE) == 0) { // the flow info is flat >- result = FlowInfo.conditional(result, result.copy()); >+ result = FlowInfo.conditional(result.copy(), result.copy()); >+ // TODO (maxime) check, reintroduced copy > } > checkNullComparison(currentScope, flowContext, result, result.initsWhenTrue(), result.initsWhenFalse()); > return result; >Index: compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java,v >retrieving revision 1.48 >diff -u -r1.48 InstanceOfExpression.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java 28 Mar 2006 20:29:56 -0000 1.48 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java 21 Apr 2006 14:13:19 -0000 >@@ -41,10 +41,10 @@ > this.expression, FlowContext.CAN_ONLY_NULL, flowInfo); > flowInfo = expression.analyseCode(currentScope, flowContext, flowInfo). > unconditionalInits(); >- FlowInfo initsWhenFalse = flowInfo.copy(); >- flowInfo.markAsComparedEqualToNonNull(local); >+ FlowInfo initsWhenTrue = flowInfo.copy(); >+ initsWhenTrue.markAsComparedEqualToNonNull(local); > // no impact upon enclosing try context >- return FlowInfo.conditional(flowInfo, initsWhenFalse); >+ return FlowInfo.conditional(initsWhenTrue, flowInfo.copy()); > } > return expression.analyseCode(currentScope, flowContext, flowInfo). > unconditionalInits(); >Index: .settings/org.eclipse.jdt.core.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs,v >retrieving revision 1.7 >diff -u -r1.7 org.eclipse.jdt.core.prefs >--- .settings/org.eclipse.jdt.core.prefs 17 Feb 2006 16:06:06 -0000 1.7 >+++ .settings/org.eclipse.jdt.core.prefs 21 Apr 2006 14:13:19 -0000 >@@ -1,4 +1,4 @@ >-#Fri Feb 17 16:48:15 CET 2006 >+#Mon Mar 20 16:28:55 CET 2006 > eclipse.preferences.version=1 > org.eclipse.jdt.core.builder.cleanOutputFolder=clean > org.eclipse.jdt.core.builder.duplicateResourceTask=warning >#P org.eclipse.jdt.core.tests.compiler >Index: .settings/org.eclipse.jdt.core.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.jdt.core.prefs,v >retrieving revision 1.10 >diff -u -r1.10 org.eclipse.jdt.core.prefs >--- .settings/org.eclipse.jdt.core.prefs 30 Sep 2005 14:41:40 -0000 1.10 >+++ .settings/org.eclipse.jdt.core.prefs 21 Apr 2006 14:13:23 -0000 >@@ -1,4 +1,4 @@ >-#Fri Sep 30 16:39:41 CEST 2005 >+#Thu Feb 23 14:36:02 CET 2006 > eclipse.preferences.version=1 > org.eclipse.jdt.core.builder.cleanOutputFolder=clean > org.eclipse.jdt.core.builder.duplicateResourceTask=warning >@@ -66,5 +66,251 @@ > org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning > org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning > org.eclipse.jdt.core.compiler.source=1.3 >+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_assignment=0 >+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 >+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 >+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 >+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 >+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_after_package=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_field=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 >+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_method=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_package=0 >+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 >+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false >+org.eclipse.jdt.core.formatter.comment.format_comments=true >+org.eclipse.jdt.core.formatter.comment.format_header=false >+org.eclipse.jdt.core.formatter.comment.format_html=true >+org.eclipse.jdt.core.formatter.comment.format_source_code=true >+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true >+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true >+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert >+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert >+org.eclipse.jdt.core.formatter.comment.line_length=80 >+org.eclipse.jdt.core.formatter.compact_else_if=true >+org.eclipse.jdt.core.formatter.continuation_indentation=2 >+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 >+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true >+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_empty_lines=false >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false >+org.eclipse.jdt.core.formatter.indentation.size=4 >+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert >+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert >+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert >+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.lineSplit=80 >+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 >+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 >+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true >+org.eclipse.jdt.core.formatter.tabulation.char=tab >+org.eclipse.jdt.core.formatter.tabulation.size=4 >+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false > org.eclipse.jdt.core.incompatibleJDKLevel=ignore > org.eclipse.jdt.core.incompleteClasspath=error >Index: src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java,v >retrieving revision 1.60 >diff -u -r1.60 AbstractRegressionTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 7 Apr 2006 09:03:47 -0000 1.60 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 21 Apr 2006 14:13:23 -0000 >@@ -832,7 +832,8 @@ > // start with the current directory which contains the source files > Process compileProcess = Runtime.getRuntime().exec( > cmdLineHeader.toString() + " -version", null, null); >- Logger versionLogger = new Logger(compileProcess.getErrorStream(), ""); // WORK >+ Logger versionLogger = new Logger(compileProcess.getErrorStream(), ""); >+ // PREMATURE implement consistent error policy > versionLogger.start(); > compileProcess.waitFor(); > versionLogger.join(); // make sure we get the whole output >@@ -1148,8 +1149,9 @@ > javaCmdLine.append(' ').append(testFiles[0].substring(0, testFiles[0].indexOf('.'))); > // assume executable class is name of first test file - PREMATURE check if this is also the case in other test fwk classes > execProcess = Runtime.getRuntime().exec(javaCmdLine.toString(), null, this.outputTestDirectoryPath.toFile()); >- Logger logger = new Logger(execProcess.getInputStream(), ""); // WORK >- logger.start(); >+ Logger logger = new Logger(execProcess.getInputStream(), ""); >+ // PREMATURE implement consistent error policy >+ logger.start(); > exitValue = execProcess.waitFor(); > logger.join(); // make sure we get the whole output > String javaOutput = logger.buffer.toString().trim(); >Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java,v >retrieving revision 1.33 >diff -u -r1.33 NullReferenceTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 6 Apr 2006 08:38:51 -0000 1.33 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 21 Apr 2006 14:13:24 -0000 >@@ -11,16 +11,11 @@ > package org.eclipse.jdt.core.tests.compiler.regression; > > import java.util.Map; >- >-import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; >-import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo.AssertionFailedException; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; >- >-import junit.framework.AssertionFailedError; > import junit.framework.Test; > >+/* See also NullReferenceImplTests for low level, implementation dependent >+ * tests. */ > public class NullReferenceTest extends AbstractRegressionTest { > > public NullReferenceTest(String name) { >@@ -1730,15 +1725,6 @@ > } > > // null analysis - if/else >-// PMT: exactly the case we talked about; what happens is that the first >-// if shade doubts upon o; what we could do is to avoid marking in case >-// of error? not sure this is appropriate though, because of inner code >-// into the if itself; I believe I somewhat did that on purpose: the latest >-// wins; completed with o.toString()... >-// basically, the choice is about what we should do in case of error: >-// neglect the effect of the error, or propagate this effect; the second >-// tends to produce less repeated errors (I believe) than the first... >-// PREMATURE could refine adding a null-dependent reachable mark... not urgent > public void test0312_if_else() { > this.runNegativeTest( > new String[] { >@@ -1748,8 +1734,8 @@ > " void foo() {\n" + > " Object o = new Object();\n" + > " if (o == null) { /* */ }\n" + // complain >- " if (o != null) { /* */ }\n" + // quiet >- " o.toString();\n" + // complain >+ " if (o != null) { /* */ }\n" + >+ " o.toString();\n" + > " }\n" + > "}\n"}, > "----------\n" + >@@ -2376,6 +2362,100 @@ > ""); > } > >+// null analysis - if/else nested with unknown protection: unknown cannot protect >+public void test0339_if_else_nested() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o, boolean b) {\n" + >+ " if (o == null || b) {\n" + >+ " if (bar() == o) {\n" + >+ " o.toString();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " Object bar() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " o.toString();\n" + >+ " ^\n" + >+ "The variable o may be null\n" + >+ "----------\n"); >+} >+ >+// null analysis - if/else nested >+public void test0340_if_else_nested() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o) {\n" + >+ " if (o == null) {\n" + >+ " if (bar() == o) {\n" + >+ " o.toString();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " Object bar() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " o.toString();\n" + >+ " ^\n" + >+ "The variable o can only be null; it was either set to null or checked for null when last used\n" + >+ "----------\n"); >+} >+ >+// null analysis - if/else nested >+public void test0341_if_else_nested() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o1, Object o2, boolean b) {\n" + >+ " if (o1 == null || b) {\n" + >+ " if (o1 == o2) {\n" + >+ " o1.toString();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " o1.toString();\n" + >+ " ^^\n" + >+ "The variable o1 may be null\n" + >+ "----------\n"); >+} >+ >+// null analysis - if/else nested >+public void test0342_if_else_nested() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o1, Object o2, boolean b) {\n" + >+ " if (o1 == null || b) {\n" + >+ " if (o2 == o1) {\n" + >+ " o1.toString();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " o1.toString();\n" + >+ " ^^\n" + >+ "The variable o1 may be null\n" + >+ "----------\n"); >+} >+ > // null analysis -- while > public void test0401_while() { > this.runNegativeTest( >@@ -3511,7 +3591,8 @@ > > // null analysis - while > // TODO (maxime) https://bugs.eclipse.org/bugs/show_bug.cgi?id=133131 >-public void _test0451_while_nested() { >+// fixed along 127570, do the reporting >+public void test0451_while_nested() { > this.runNegativeTest( > new String[] { > "X.java", >@@ -3526,7 +3607,12 @@ > " if (o != null) { /* */ }\n" + > " }\n" + > "}"}, >- "ERR"); >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " if (o != null) { /* */ }\n" + >+ " ^\n" + >+ "The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + >+ "----------\n"); > } > > // TODO (maxime) https://bugs.eclipse.org/bugs/show_bug.cgi?id=123399 >@@ -5357,9 +5443,10 @@ > } > > // null analysis -- for >-// contrast this with #311 >+// changed with https://bugs.eclipse.org/bugs/show_bug.cgi?id=127570 >+// we are now able to see that x2 is reinitialized with x1, which is unknown > public void test0726_for() { >- this.runNegativeTest( >+ this.runConformTest( > new String[] { > "X.java", > "public class X {\n" + >@@ -5373,12 +5460,7 @@ > " }\n" + > " }\n" + > "}\n"}, >- "----------\n" + >- "1. ERROR in X.java (at line 8)\n" + >- " x2.toString();\n" + >- " ^^\n" + >- "The variable x2 may be null\n" + >- "----------\n"); >+ ""); > } > > // null analysis -- for >@@ -5587,6 +5669,89 @@ > } > } > >+// null analysis - for >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127570 >+public void test0736_for_embedded_lazy_init() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "class X {\n" + >+ " public boolean foo() {\n" + >+ " Boolean b = null;\n" + >+ " for (int i = 0; i < 1; i++) {\n" + >+ " if (b == null) {\n" + >+ " b = Boolean.TRUE;\n" + >+ " }\n" + >+ " if (b.booleanValue()) {\n" + // quiet >+ " return b.booleanValue();\n" + >+ " }\n" + >+ " }\n" + >+ " return false;\n" + >+ " }\n" + >+ "}"}, >+ ""); >+} >+ >+// null analysis - for with unknown protection: unknown cannot protect anything >+// suggested by https://bugs.eclipse.org/bugs/show_bug.cgi?id=127570 >+public void test0737_for_unknown_protection() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "class X {\n" + >+ " public boolean foo(Boolean p) {\n" + >+ " Boolean b = null;\n" + >+ " for (int i = 0; i < 1; i++) {\n" + >+ " if (b == p) {\n" + // tells us that p is null as well >+ " // empty\n" + >+ " }\n" + >+ " else {\n" + >+ " continue;\n" + >+ " }\n" + >+ " if (b.booleanValue()) {\n" + // complain b can only be null >+ " return b.booleanValue();\n" + >+ " }\n" + >+ " }\n" + >+ " return false;\n" + >+ " }\n" + >+ "}"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " if (b.booleanValue()) {\n" + >+ " ^\n" + >+ "The variable b can only be null; it was either set to null or checked for null when last used\n" + >+ "----------\n"); >+} >+ >+// null analysis - for with unknown protection >+// suggested by https://bugs.eclipse.org/bugs/show_bug.cgi?id=127570 >+// the issue is that we cannot do less than full aliasing analysis to >+// catch this one >+// TODO (maxime) reconsider when/if we bring full aliasing in >+public void _test0738_for_unknown_protection() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "class X {\n" + >+ " public boolean foo(Boolean p) {\n" + >+ " Boolean b = null;\n" + >+ " for (int i = 0; i < 1; i++) {\n" + >+ " if (b == p) {\n" + >+ " // empty\n" + >+ " }\n" + >+ " else {\n" + >+ " b = p;\n" + >+ " }\n" + >+ " if (b.booleanValue()) {\n" + // quiet because b is an alias for p, unknown >+ " return b.booleanValue();\n" + >+ " }\n" + >+ " }\n" + >+ " return false;\n" + >+ " }\n" + >+ "}"}, >+ ""); >+} >+ > // null analysis -- switch > public void test0800_switch() { > this.runConformTest( >@@ -7035,6 +7200,109 @@ > "----------\n"); > } > >+// encoding validation >+public void test1500() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o, int i, boolean b, Object u) {\n" + >+ " o.toString();\n" + >+ " switch (i) {\n" + >+ " case 0:\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " } else {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " break;\n" + >+ " }\n" + >+ " if (o == null) { /* empty */ }\n" + >+ " }\n" + >+ "}\n"}, >+ ""); >+} >+ >+// encoding validation >+public void test1501() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o, int i, boolean b, Object u) {\n" + >+ " if (b) {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " o.toString();\n" + >+ " switch (i) {\n" + >+ " case 0:\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " } else {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " break;\n" + >+ " }\n" + >+ " if (o == null) { /* empty */ }\n" + >+ " }\n" + >+ "}\n"}, >+ ""); >+} >+ >+// encoding validation >+public void test1502() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o, int i, boolean b, Object u) {\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " }\n" + >+ " o.toString();\n" + >+ " switch (i) {\n" + >+ " case 0:\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " } else {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " break;\n" + >+ " }\n" + >+ " if (o == null) { /* empty */ }\n" + >+ " }\n" + >+ "}\n"}, >+ ""); >+} >+ >+// encoding validation >+public void test1503() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Object o, int i, boolean b, Object u) {\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " } else {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " o.toString();\n" + >+ " switch (i) {\n" + >+ " case 0:\n" + >+ " if (b) {\n" + >+ " o = u;\n" + >+ " } else {\n" + >+ " o = new Object();\n" + >+ " }\n" + >+ " break;\n" + >+ " }\n" + >+ " if (o == null) { /* empty */ }\n" + >+ " }\n" + >+ "}\n"}, >+ ""); >+} >+ > // flow info low-level validation > public void test2000_flow_info() { > this.runNegativeTest( >@@ -7058,7 +7326,7 @@ > " o60 = o0, o61 = o0, o62 = o0, o63 = o0, o64 = o0,\n" + > " o65 = o0, o66 = o0, o67 = o0, o68 = o0, o69 = o0;\n" + > " if (o65 == null) { /* */ }\n" + // complain >- " if (o65 != null) { /* */ }\n" + // quiet (already reported) >+ " if (o65 != null) { /* */ }\n" + > " }\n" + > "}\n"}, > "----------\n" + >@@ -7782,2197 +8050,4 @@ > "The variable o1 may be null\n" + > "----------\n"); > } >- >-// Technical tests -- only available with patched sources >-static final boolean >- printTablesAsNames = false, >- printTablesAsCodes = false, >- printTruthMaps = false; >-static final int >- combinationTestsloopsNb = 1; // define to 10000s to measure performances >- >- >-public void test2050_markAsComparedEqualToNonNull() { >- long [][][] testData = { >- {{0,0,0,0},{1,1,0,0}}, >- {{0,0,0,1},{1,1,0,1}}, >- {{0,0,1,0},{1,1,0,0}}, >- {{0,0,1,1},{1,1,0,1}}, >- {{0,1,0,0},{1,1,0,0}}, >- {{0,1,0,1},{1,1,0,1}}, >- {{0,1,1,0},{1,1,0,0}}, >- {{0,1,1,1},{1,1,0,1}}, >- {{1,0,0,0},{1,1,0,0}}, >- {{1,0,0,1},{1,0,0,1}}, >- {{1,0,1,0},{1,1,0,0}}, >- {{1,0,1,1},{1,1,0,1}}, >- {{1,1,0,0},{1,1,0,0}}, >- {{1,1,0,1},{1,1,0,1}}, >- {{1,1,1,0},{1,1,0,0}}, >- {{1,1,1,1},{1,1,0,1}}, >- }; >- int failures = 0; >- LocalVariableBinding local = new TestLocalVariableBinding(0); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- result.markAsComparedEqualToNonNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1])))) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- local = new TestLocalVariableBinding(64); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64), >- expected = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64); >- result.markAsComparedEqualToNonNull(local); >- if (!(result.testEquals(expected))) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (64) instead of: " + testStringValueOf(testData[i][1])); >- } >- if (testData[i][0][0] == 0 && >- testData[i][0][1] == 0 && >- testData[i][0][2] == 0 && >- testData[i][0][3] == 0) { >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1]); >- result.markAsComparedEqualToNonNull(local); >- if (!result.testEquals(expected, 64)) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (zero 64) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- } >- local = new TestLocalVariableBinding(128); >- for (int i = 0; i < testData.length; i++) { >- if (testData[i][0][0] == 0 && >- testData[i][0][1] == 0 && >- testData[i][0][2] == 0 && >- testData[i][0][3] == 0) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64), >- expected = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128); >- result.markAsComparedEqualToNonNull(local); >- if (!result.testEquals(expected, 128)) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (zero 128) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MARK COMPARED NON NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + >- testSymbolicValueOf(testData[i][1])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MARK COMPARED NON NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1])); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2051_markAsComparedEqualToNull() { >- long [][][] testData = { >- {{0,0,0,0},{0,1,0,0}}, >- {{0,0,0,1},{0,1,0,0}}, >- {{0,0,1,0},{0,1,1,0}}, >- {{0,0,1,1},{0,1,1,0}}, >- {{0,1,0,0},{0,1,0,0}}, >- {{0,1,0,1},{0,1,0,0}}, >- {{0,1,1,0},{0,1,1,0}}, >- {{0,1,1,1},{0,1,1,0}}, >- {{1,0,0,0},{0,1,0,0}}, >- {{1,0,0,1},{0,1,0,0}}, >- {{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,1},{0,1,0,0}}, >- {{1,1,0,0},{0,1,0,0}}, >- {{1,1,0,1},{0,1,0,0}}, >- {{1,1,1,0},{0,1,1,0}}, >- {{1,1,1,1},{0,1,1,0}}, >- }; >- int failures = 0; >- LocalVariableBinding local = new TestLocalVariableBinding(0); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- result.markAsComparedEqualToNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1])))) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- local = new TestLocalVariableBinding(64); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64), >- expected = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64); >- result.markAsComparedEqualToNull(local); >- if (!(result.testEquals(expected))) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (64) instead of: " + testStringValueOf(testData[i][1])); >- } >- if (testData[i][0][0] == 0 && >- testData[i][0][1] == 0 && >- testData[i][0][2] == 0 && >- testData[i][0][3] == 0) { >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1]); >- result.markAsComparedEqualToNull(local); >- if (!result.testEquals(expected, 64)) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (zero 64) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- } >- local = new TestLocalVariableBinding(128); >- for (int i = 0; i < testData.length; i++) { >- if (testData[i][0][0] == 0 && >- testData[i][0][1] == 0 && >- testData[i][0][2] == 0 && >- testData[i][0][3] == 0) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64), >- expected = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128); >- result.markAsComparedEqualToNull(local); >- if (!result.testEquals(expected, 128)) { >- if (failures == 0) { >- System.out.println("markAsComparedEqualToNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (zero 128) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MARK COMPARED NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + >- testSymbolicValueOf(testData[i][1])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MARK COMPARED NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1])); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2052_markAsDefinitelyNonNull() { >- long [][][] testData = { >- {{0,0,0,0},{1,0,0,1}}, >- {{0,0,0,1},{1,0,0,1}}, >- {{0,0,1,0},{1,0,0,1}}, >- {{0,0,1,1},{1,0,0,1}}, >- {{0,1,0,0},{1,0,0,1}}, >- {{0,1,0,1},{1,0,0,1}}, >- {{0,1,1,0},{1,0,0,1}}, >- {{0,1,1,1},{1,0,0,1}}, >- {{1,0,0,0},{1,0,0,1}}, >- {{1,0,0,1},{1,0,0,1}}, >- {{1,0,1,0},{1,0,0,1}}, >- {{1,0,1,1},{1,0,0,1}}, >- {{1,1,0,0},{1,0,0,1}}, >- {{1,1,0,1},{1,0,0,1}}, >- {{1,1,1,0},{1,0,0,1}}, >- {{1,1,1,1},{1,0,0,1}}, >- }; >- int failures = 0; >- LocalVariableBinding local = new TestLocalVariableBinding(0); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- result.markAsDefinitelyNonNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1])))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- local = new TestLocalVariableBinding(64); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- result.markAsDefinitelyNonNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64)))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyNonNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (64) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY NON NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + >- testSymbolicValueOf(testData[i][1])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY NON NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1])); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2053_markAsDefinitelyNull() { >- long [][][] testData = { >- {{0,0,0,0},{1,0,1,0}}, >- {{0,0,0,1},{1,0,1,0}}, >- {{0,0,1,0},{1,0,1,0}}, >- {{0,0,1,1},{1,0,1,0}}, >- {{0,1,0,0},{1,0,1,0}}, >- {{0,1,0,1},{1,0,1,0}}, >- {{0,1,1,0},{1,0,1,0}}, >- {{0,1,1,1},{1,0,1,0}}, >- {{1,0,0,0},{1,0,1,0}}, >- {{1,0,0,1},{1,0,1,0}}, >- {{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,1},{1,0,1,0}}, >- {{1,1,0,0},{1,0,1,0}}, >- {{1,1,0,1},{1,0,1,0}}, >- {{1,1,1,0},{1,0,1,0}}, >- {{1,1,1,1},{1,0,1,0}}, >- }; >- int failures = 0; >- LocalVariableBinding local = new TestLocalVariableBinding(0); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- result.markAsDefinitelyNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1])))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- local = new TestLocalVariableBinding(64); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- result.markAsDefinitelyNull(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64)))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyNull failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (64) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + >- testSymbolicValueOf(testData[i][1])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY NULL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1])); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2054_markAsDefinitelyUnknown() { >- long [][][] testData = { >- {{0,0,0,0},{1,0,1,1}}, >- {{0,0,0,1},{1,0,1,1}}, >- {{0,0,1,0},{1,0,1,1}}, >- {{0,0,1,1},{1,0,1,1}}, >- {{0,1,0,0},{1,0,1,1}}, >- {{0,1,0,1},{1,0,1,1}}, >- {{0,1,1,0},{1,0,1,1}}, >- {{0,1,1,1},{1,0,1,1}}, >- {{1,0,0,0},{1,0,1,1}}, >- {{1,0,0,1},{1,0,1,1}}, >- {{1,0,1,0},{1,0,1,1}}, >- {{1,0,1,1},{1,0,1,1}}, >- {{1,1,0,0},{1,0,1,1}}, >- {{1,1,0,1},{1,0,1,1}}, >- {{1,1,1,0},{1,0,1,1}}, >- {{1,1,1,1},{1,0,1,1}}, >- }; >- int failures = 0; >- LocalVariableBinding local = new TestLocalVariableBinding(0); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- result.markAsDefinitelyUnknown(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1])))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyUnknown failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- local = new TestLocalVariableBinding(64); >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness >- result = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- result.markAsDefinitelyUnknown(local); >- if (!(result.testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64)))) { >- if (failures == 0) { >- System.out.println("markAsDefinitelyUnknown failures: "); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + result.testString() + >- "}, // (64) instead of: " + testStringValueOf(testData[i][1])); >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY UNKNOWN"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + >- testSymbolicValueOf(testData[i][1])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MARK DEFINITELY UNKNOWN"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1])); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2055_addInitializationsFrom() { >- long [][][] testData = { >- {{0,0,0,0},{0,0,0,0},{0,0,0,0}}, >- {{0,0,0,0},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,0},{0,1,0,0},{0,1,0,0}}, >- {{0,0,0,0},{0,1,1,0},{0,1,1,0}}, >- {{0,0,0,0},{1,0,0,1},{1,0,0,1}}, >- {{0,0,0,0},{1,0,1,0},{1,0,1,0}}, >- {{0,0,0,0},{1,0,1,1},{1,0,1,1}}, >- {{0,0,0,0},{1,1,0,0},{1,1,0,0}}, >- {{0,0,0,0},{1,1,0,1},{1,1,0,1}}, >- {{0,0,0,1},{0,0,0,0},{0,0,0,1}}, >- {{0,0,0,1},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,1},{0,1,0,0},{0,1,0,0}}, >- {{0,0,0,1},{0,1,1,0},{0,1,0,0}}, >- {{0,0,0,1},{1,0,0,1},{1,0,0,1}}, >- {{0,0,0,1},{1,0,1,0},{1,0,1,0}}, >- {{0,0,0,1},{1,0,1,1},{1,0,1,1}}, >- {{0,0,0,1},{1,1,0,0},{1,1,0,1}}, >- {{0,0,0,1},{1,1,0,1},{1,1,0,1}}, >- {{0,0,1,0},{0,0,0,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,0},{0,1,0,0},{0,1,1,0}}, >- {{0,0,1,0},{0,1,1,0},{0,1,1,0}}, >- {{0,0,1,0},{1,0,0,1},{1,0,0,1}}, >- {{0,0,1,0},{1,0,1,0},{1,0,1,0}}, >- {{0,0,1,0},{1,0,1,1},{1,0,1,1}}, >- {{0,0,1,0},{1,1,0,0},{1,1,0,0}}, >- {{0,0,1,0},{1,1,0,1},{1,1,0,1}}, >- {{0,0,1,1},{0,0,0,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,1},{0,1,0,0},{0,1,1,0}}, >- {{0,0,1,1},{0,1,1,0},{0,1,1,0}}, >- {{0,0,1,1},{1,0,0,1},{1,0,0,1}}, >- {{0,0,1,1},{1,0,1,0},{1,0,1,0}}, >- {{0,0,1,1},{1,0,1,1},{1,0,1,1}}, >- {{0,0,1,1},{1,1,0,0},{1,1,0,1}}, >- {{0,0,1,1},{1,1,0,1},{1,1,0,1}}, >- {{0,1,0,0},{0,0,0,0},{0,1,0,0}}, >- {{0,1,0,0},{0,0,0,1},{0,0,0,1}}, >- {{0,1,0,0},{0,0,1,0},{0,1,1,0}}, >- {{0,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,0,0},{0,1,0,0},{0,1,0,0}}, >- {{0,1,0,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,0,0},{1,0,0,1},{1,0,0,1}}, >- {{0,1,0,0},{1,0,1,0},{1,0,1,0}}, >- {{0,1,0,0},{1,0,1,1},{1,0,1,1}}, >- {{0,1,0,0},{1,1,0,0},{1,1,0,0}}, >- {{0,1,0,0},{1,1,0,1},{1,1,0,1}}, >- {{0,1,1,0},{0,0,0,0},{0,1,1,0}}, >- {{0,1,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,1,1,0},{0,0,1,0},{0,1,1,0}}, >- {{0,1,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,1,0},{0,1,0,0},{0,1,1,0}}, >- {{0,1,1,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,1,0},{1,0,0,1},{1,0,0,1}}, >- {{0,1,1,0},{1,0,1,0},{1,0,1,0}}, >- {{0,1,1,0},{1,0,1,1},{1,0,1,1}}, >- {{0,1,1,0},{1,1,0,0},{1,1,0,0}}, >- {{0,1,1,0},{1,1,0,1},{1,1,0,1}}, >- {{1,0,0,1},{0,0,0,0},{1,0,0,1}}, >- {{1,0,0,1},{0,0,0,1},{1,0,0,1}}, >- {{1,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,0,1},{0,1,0,0},{0,1,0,0}}, >- {{1,0,0,1},{0,1,1,0},{0,1,1,0}}, >- {{1,0,0,1},{1,0,0,1},{1,0,0,1}}, >- {{1,0,0,1},{1,0,1,0},{1,0,1,0}}, >- {{1,0,0,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,0,1},{1,1,0,0},{1,1,0,1}}, >- {{1,0,0,1},{1,1,0,1},{1,1,0,1}}, >- {{1,0,1,0},{0,0,0,0},{1,0,1,0}}, >- {{1,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{1,0,1,0},{0,0,1,0},{1,0,1,0}}, >- {{1,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,0},{0,1,0,0},{1,0,1,0}}, >- {{1,0,1,0},{0,1,1,0},{1,0,1,0}}, >- {{1,0,1,0},{1,0,0,1},{1,0,0,1}}, >- {{1,0,1,0},{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,0},{1,0,1,1},{1,0,1,1}}, >- {{1,0,1,0},{1,1,0,0},{1,1,0,0}}, >- {{1,0,1,0},{1,1,0,1},{1,1,0,1}}, >- {{1,0,1,1},{0,0,0,0},{1,0,1,1}}, >- {{1,0,1,1},{0,0,0,1},{1,0,1,1}}, >- {{1,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,1},{0,1,0,0},{0,1,0,0}}, >- {{1,0,1,1},{0,1,1,0},{0,1,1,0}}, >- {{1,0,1,1},{1,0,0,1},{1,0,0,1}}, >- {{1,0,1,1},{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,1,1},{1,1,0,0},{1,1,0,1}}, >- {{1,0,1,1},{1,1,0,1},{1,1,0,1}}, >- {{1,1,0,0},{0,0,0,0},{1,1,0,0}}, >- {{1,1,0,0},{0,0,0,1},{1,1,0,1}}, >- {{1,1,0,0},{0,0,1,0},{0,0,1,0}}, >- {{1,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,0},{0,1,0,0},{0,1,0,0}}, >- {{1,1,0,0},{0,1,1,0},{0,1,1,0}}, >- {{1,1,0,0},{1,0,0,1},{1,0,0,1}}, >- {{1,1,0,0},{1,0,1,0},{1,0,1,0}}, >- {{1,1,0,0},{1,0,1,1},{1,0,1,1}}, >- {{1,1,0,0},{1,1,0,0},{1,1,0,0}}, >- {{1,1,0,0},{1,1,0,1},{1,1,0,1}}, >- {{1,1,0,1},{0,0,0,0},{1,1,0,1}}, >- {{1,1,0,1},{0,0,0,1},{0,0,0,1}}, >- {{1,1,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,1,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,1},{0,1,0,0},{0,1,0,0}}, >- {{1,1,0,1},{0,1,1,0},{0,1,1,0}}, >- {{1,1,0,1},{1,0,0,1},{1,0,0,1}}, >- {{1,1,0,1},{1,0,1,0},{1,0,1,0}}, >- {{1,1,0,1},{1,0,1,1},{1,0,1,1}}, >- {{1,1,0,1},{1,1,0,0},{1,1,0,1}}, >- {{1,1,0,1},{1,1,0,1},{1,1,0,1}}, >- }; >- int failures = 0; >- long start; >- if (combinationTestsloopsNb > 1) { >- start = System.currentTimeMillis(); >- } >- String header = "addInitializationsFrom failures: "; //$NON-NLS-1$ >- for (int l = 0; l < combinationTestsloopsNb ; l++) { >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness result; >- if (!(result = (UnconditionalFlowInfoTestHarness)( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0])). >- addInitializationsFrom( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1]))). >- testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2]))) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- } >- if (combinationTestsloopsNb > 1) { >- System.out.println("addInitial...\t\t" + combinationTestsloopsNb + "\t" + >- (System.currentTimeMillis() - start)); >- } >- // PREMATURE optimize test (extraneous allocations and copies) >- // PREMATURE optimize test (extraneous iterations - undup) >- UnconditionalFlowInfoTestHarness >- zero = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(new long[] {0,0,0,0}), >- left0, left1, right1, left2, right2, >- expected0, expected1, expected2, result; >- for (int i = 0; i < testData.length; i++) { >- left0 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- left1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- left2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 128); >- right1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64); >- right2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128); >- expected0 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2]); >- expected1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 64); >- expected2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 128); >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addInitializationsFrom(right1)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if ((testData[i][0][0] | testData[i][0][1] | >- testData[i][0][2] | testData[i][0][3]) == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- zero.copy().addInitializationsFrom(right1)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) right2.copy(). >- addInitializationsFrom(right1)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- zero.copy().addInitializationsFrom(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString(128) + >- "}, // (zero, 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- right1.copy().addInitializationsFrom(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString(128) + >- "}, // (zero 64, 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- if ((testData[i][1][0] | testData[i][1][1] | >- testData[i][1][2] | testData[i][1][3]) == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left0.copy().addInitializationsFrom(left2)). >- testEquals(expected0, 0)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (1, zero 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addInitializationsFrom(zero)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addInitializationsFrom(left2)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left2.copy().addInitializationsFrom(zero)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left2.addInitializationsFrom(left1)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR ADD"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + >- testSymbolicValueOf(testData[i][1]) + " -> " + >- testSymbolicValueOf(testData[i][2])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR ADD"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1]) + " " + >- testCodedValueOf(testData[i][2])); >- } >- } >- if (printTruthMaps) { >- for (int i = 0; i < 4; i++) { >- System.out.println("======================================================"); >- System.out.println("Truth map for addInitializationsFrom null bit " + (i + 1)); >- System.out.println(); >- printTruthMap(testData, i); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2056_addPotentialInitializationsFrom() { >- long [][][] testData = { >- {{0,0,0,0},{0,0,0,0},{0,0,0,0}}, >- {{0,0,0,0},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,0},{0,1,0,0},{0,0,0,0}}, >- {{0,0,0,0},{0,1,1,0},{0,0,1,0}}, >- {{0,0,0,0},{1,0,0,1},{0,0,0,1}}, >- {{0,0,0,0},{1,0,1,0},{0,0,1,0}}, >- {{0,0,0,0},{1,0,1,1},{0,0,0,1}}, >- {{0,0,0,0},{1,1,0,0},{0,0,0,0}}, >- {{0,0,0,0},{1,1,0,1},{0,0,0,1}}, >- {{0,0,0,1},{0,0,0,0},{0,0,0,1}}, >- {{0,0,0,1},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,1},{0,1,0,0},{0,0,0,1}}, >- {{0,0,0,1},{0,1,1,0},{0,0,1,1}}, >- {{0,0,0,1},{1,0,0,1},{0,0,0,1}}, >- {{0,0,0,1},{1,0,1,0},{0,0,1,1}}, >- {{0,0,0,1},{1,0,1,1},{0,0,0,1}}, >- {{0,0,0,1},{1,1,0,0},{0,0,0,1}}, >- {{0,0,0,1},{1,1,0,1},{0,0,0,1}}, >- {{0,0,1,0},{0,0,0,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,0},{0,1,0,0},{0,0,1,0}}, >- {{0,0,1,0},{0,1,1,0},{0,0,1,0}}, >- {{0,0,1,0},{1,0,0,1},{0,0,1,1}}, >- {{0,0,1,0},{1,0,1,0},{0,0,1,0}}, >- {{0,0,1,0},{1,0,1,1},{0,0,1,1}}, >- {{0,0,1,0},{1,1,0,0},{0,0,1,0}}, >- {{0,0,1,0},{1,1,0,1},{0,0,1,1}}, >- {{0,0,1,1},{0,0,0,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,1},{0,1,0,0},{0,0,1,1}}, >- {{0,0,1,1},{0,1,1,0},{0,0,1,1}}, >- {{0,0,1,1},{1,0,0,1},{0,0,1,1}}, >- {{0,0,1,1},{1,0,1,0},{0,0,1,1}}, >- {{0,0,1,1},{1,0,1,1},{0,0,1,1}}, >- {{0,0,1,1},{1,1,0,0},{0,0,1,1}}, >- {{0,0,1,1},{1,1,0,1},{0,0,1,1}}, >- {{0,1,0,0},{0,0,0,0},{0,1,0,0}}, >- {{0,1,0,0},{0,0,0,1},{0,0,0,1}}, >- {{0,1,0,0},{0,0,1,0},{0,1,1,0}}, >- {{0,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,0,0},{0,1,0,0},{0,1,0,0}}, >- {{0,1,0,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,0,0},{1,0,0,1},{0,0,0,1}}, >- {{0,1,0,0},{1,0,1,0},{0,1,1,0}}, >- {{0,1,0,0},{1,0,1,1},{0,0,0,1}}, >- {{0,1,0,0},{1,1,0,0},{0,1,0,0}}, >- {{0,1,0,0},{1,1,0,1},{0,0,0,1}}, >- {{0,1,1,0},{0,0,0,0},{0,1,1,0}}, >- {{0,1,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,1,1,0},{0,0,1,0},{0,1,1,0}}, >- {{0,1,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,1,0},{0,1,0,0},{0,1,1,0}}, >- {{0,1,1,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,1,0},{1,0,0,1},{0,0,1,1}}, >- {{0,1,1,0},{1,0,1,0},{0,1,1,0}}, >- {{0,1,1,0},{1,0,1,1},{0,0,1,1}}, >- {{0,1,1,0},{1,1,0,0},{0,1,1,0}}, >- {{0,1,1,0},{1,1,0,1},{0,0,1,1}}, >- {{1,0,0,1},{0,0,0,0},{1,0,0,1}}, >- {{1,0,0,1},{0,0,0,1},{1,0,1,1}}, >- {{1,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,0,1},{0,1,0,0},{1,0,0,1}}, >- {{1,0,0,1},{0,1,1,0},{0,0,1,1}}, >- {{1,0,0,1},{1,0,0,1},{1,0,0,1}}, >- {{1,0,0,1},{1,0,1,0},{0,0,1,1}}, >- {{1,0,0,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,0,1},{1,1,0,0},{1,0,0,1}}, >- {{1,0,0,1},{1,1,0,1},{1,0,0,1}}, >- {{1,0,1,0},{0,0,0,0},{1,0,1,0}}, >- {{1,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{1,0,1,0},{0,0,1,0},{1,0,1,0}}, >- {{1,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,0},{0,1,0,0},{1,0,1,0}}, >- {{1,0,1,0},{0,1,1,0},{1,0,1,0}}, >- {{1,0,1,0},{1,0,0,1},{0,0,1,1}}, >- {{1,0,1,0},{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,0},{1,0,1,1},{0,0,1,1}}, >- {{1,0,1,0},{1,1,0,0},{1,0,1,0}}, >- {{1,0,1,0},{1,1,0,1},{0,0,1,1}}, >- {{1,0,1,1},{0,0,0,0},{1,0,1,1}}, >- {{1,0,1,1},{0,0,0,1},{1,0,1,1}}, >- {{1,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,1},{0,1,0,0},{1,0,1,1}}, >- {{1,0,1,1},{0,1,1,0},{0,0,1,1}}, >- {{1,0,1,1},{1,0,0,1},{1,0,1,1}}, >- {{1,0,1,1},{1,0,1,0},{0,0,1,1}}, >- {{1,0,1,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,1,1},{1,1,0,0},{1,0,1,1}}, >- {{1,0,1,1},{1,1,0,1},{1,0,1,1}}, >- {{1,1,0,0},{0,0,0,0},{1,1,0,0}}, >- {{1,1,0,0},{0,0,0,1},{0,0,0,1}}, >- {{1,1,0,0},{0,0,1,0},{0,0,1,0}}, >- {{1,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,0},{0,1,0,0},{1,1,0,0}}, >- {{1,1,0,0},{0,1,1,0},{0,0,1,0}}, >- {{1,1,0,0},{1,0,0,1},{0,0,0,1}}, >- {{1,1,0,0},{1,0,1,0},{0,0,1,0}}, >- {{1,1,0,0},{1,0,1,1},{0,0,0,1}}, >- {{1,1,0,0},{1,1,0,0},{1,1,0,0}}, >- {{1,1,0,0},{1,1,0,1},{1,1,0,1}}, >- {{1,1,0,1},{0,0,0,0},{1,1,0,1}}, >- {{1,1,0,1},{0,0,0,1},{0,0,0,1}}, >- {{1,1,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,1,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,1},{0,1,0,0},{1,1,0,1}}, >- {{1,1,0,1},{0,1,1,0},{0,0,1,1}}, >- {{1,1,0,1},{1,0,0,1},{0,0,0,1}}, >- {{1,1,0,1},{1,0,1,0},{0,0,1,1}}, >- {{1,1,0,1},{1,0,1,1},{0,0,0,1}}, >- {{1,1,0,1},{1,1,0,0},{1,1,0,1}}, >- {{1,1,0,1},{1,1,0,1},{1,1,0,1}}, >- }; >- int failures = 0; >- long start; >- if (combinationTestsloopsNb > 1) { >- start = System.currentTimeMillis(); >- } >- String header = "addPotentialInitializationsFrom failures: "; //$NON-NLS-1$ >- for (int l = 0; l < combinationTestsloopsNb ; l++) { >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness result; >- if (!(result = (UnconditionalFlowInfoTestHarness)( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0])). >- addPotentialInitializationsFrom( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1]))). >- testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2]))) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][2])); >- } >- if (combinationTestsloopsNb < 2 && >- !(result = (UnconditionalFlowInfoTestHarness)( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0])). >- addPotentialNullInfoFrom( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128))). >- testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[14][0], 65), 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString(64) + >- "}, // bit 64 only, instead of: {0,0,0,0}"); >- } >- } >- } >- if (combinationTestsloopsNb > 1) { >- System.out.println("addPotential...\t" + combinationTestsloopsNb + "\t" + >- (System.currentTimeMillis() - start)); >- } >- UnconditionalFlowInfoTestHarness >- zero = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(new long[] {0,0,0,0}), >- left0, left1, right1, left2, right2, >- expected0, expected1, expected2, result; >- for (int i = 0; i < testData.length; i++) { >- left0 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]); >- left1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- left2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 128); >- right1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64); >- right2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128); >- expected0 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2]); >- expected1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 64); >- expected2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 128); >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addPotentialInitializationsFrom(right1)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (testData[i][0][0] + testData[i][0][1] + >- testData[i][0][2] + testData[i][0][3] == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- zero.copy().addPotentialInitializationsFrom(right1)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- right2.copy().addPotentialInitializationsFrom(right1)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- (UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(new long[] {0,0,0,0}, 64)). >- // make just in time to get the needed structure >- addPotentialNullInfoFrom(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero extra, 128) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfo)right2.copy()). >- addPotentialNullInfoFrom(right1)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero 128, 64) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfo)zero.copy()). >- addPotentialNullInfoFrom(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString(128) + >- "}, // (zero, 128) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfo)right1.copy()). >- addPotentialNullInfoFrom(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString(128) + >- "}, // (zero 64, 128) null only - instead of: " + testStringValueOf(testData[i][2])); >- } } >- if (testData[i][1][0] + testData[i][1][1] + >- testData[i][1][2] + testData[i][1][3] == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfoTestHarness)left0.copy()). >- addPotentialNullInfoFrom(left2)). >- testEquals(expected0, 1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (1, zero 128) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addPotentialInitializationsFrom(zero)). >- testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().addPotentialInitializationsFrom(left2)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfo)left1.copy()). >- addPotentialNullInfoFrom(left2)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero 128) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- ((UnconditionalFlowInfo)left2.copy()). >- addPotentialNullInfoFrom(zero)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left2.addPotentialNullInfoFrom(left1)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero 64) null only - instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR ADD POTENTIAL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + >- testSymbolicValueOf(testData[i][1]) + " -> " + >- testSymbolicValueOf(testData[i][2])); >- } >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR ADD POTENTIAL"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1]) + " " + >- testCodedValueOf(testData[i][2])); >- } >- } >- if (printTruthMaps) { >- for (int i = 0; i < 4; i++) { >- System.out.println("======================================================"); >- System.out.println("Truth map for addPotentialInitializationsFrom null bit " + (i + 1)); >- System.out.println(); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-public void test2057_mergedWith() { >- long [][][] testData = { >- {{0,0,0,0},{0,0,0,0},{0,0,0,0}}, >- {{0,0,0,0},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,0},{0,1,0,0},{0,0,1,0}}, >- {{0,0,0,0},{0,1,1,0},{0,0,1,0}}, >- {{0,0,0,0},{1,0,0,1},{0,0,0,1}}, >- {{0,0,0,0},{1,0,1,0},{0,0,1,0}}, >- {{0,0,0,0},{1,0,1,1},{0,0,0,1}}, >- {{0,0,0,0},{1,1,0,0},{0,0,0,0}}, >- {{0,0,0,0},{1,1,0,1},{0,0,0,1}}, >- {{0,0,0,1},{0,0,0,0},{0,0,0,1}}, >- {{0,0,0,1},{0,0,0,1},{0,0,0,1}}, >- {{0,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,0,1},{0,1,0,0},{0,0,1,1}}, >- {{0,0,0,1},{0,1,1,0},{0,0,1,1}}, >- {{0,0,0,1},{1,0,0,1},{0,0,0,1}}, >- {{0,0,0,1},{1,0,1,0},{0,0,1,1}}, >- {{0,0,0,1},{1,0,1,1},{0,0,0,1}}, >- {{0,0,0,1},{1,1,0,0},{0,0,0,1}}, >- {{0,0,0,1},{1,1,0,1},{0,0,0,1}}, >- {{0,0,1,0},{0,0,0,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,0},{0,0,1,0},{0,0,1,0}}, >- {{0,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,0},{0,1,0,0},{0,0,1,0}}, >- {{0,0,1,0},{0,1,1,0},{0,0,1,0}}, >- {{0,0,1,0},{1,0,0,1},{0,0,1,1}}, >- {{0,0,1,0},{1,0,1,0},{0,0,1,0}}, >- {{0,0,1,0},{1,0,1,1},{0,0,1,1}}, >- {{0,0,1,0},{1,1,0,0},{0,0,1,0}}, >- {{0,0,1,0},{1,1,0,1},{0,0,1,1}}, >- {{0,0,1,1},{0,0,0,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,0,1},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{0,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{0,0,1,1},{0,1,0,0},{0,0,1,1}}, >- {{0,0,1,1},{0,1,1,0},{0,0,1,1}}, >- {{0,0,1,1},{1,0,0,1},{0,0,1,1}}, >- {{0,0,1,1},{1,0,1,0},{0,0,1,1}}, >- {{0,0,1,1},{1,0,1,1},{0,0,1,1}}, >- {{0,0,1,1},{1,1,0,0},{0,0,1,1}}, >- {{0,0,1,1},{1,1,0,1},{0,0,1,1}}, >- {{0,1,0,0},{0,0,0,0},{0,0,1,0}}, >- {{0,1,0,0},{0,0,0,1},{0,0,1,1}}, >- {{0,1,0,0},{0,0,1,0},{0,0,1,0}}, >- {{0,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,0,0},{0,1,0,0},{0,1,0,0}}, >- {{0,1,0,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,0,0},{1,0,0,1},{0,0,0,1}}, >- {{0,1,0,0},{1,0,1,0},{0,1,1,0}}, >- {{0,1,0,0},{1,0,1,1},{0,0,1,1}}, >- {{0,1,0,0},{1,1,0,0},{0,0,1,0}}, >- {{0,1,0,0},{1,1,0,1},{0,0,1,1}}, >- {{0,1,1,0},{0,0,0,0},{0,0,1,0}}, >- {{0,1,1,0},{0,0,0,1},{0,0,1,1}}, >- {{0,1,1,0},{0,0,1,0},{0,0,1,0}}, >- {{0,1,1,0},{0,0,1,1},{0,0,1,1}}, >- {{0,1,1,0},{0,1,0,0},{0,1,1,0}}, >- {{0,1,1,0},{0,1,1,0},{0,1,1,0}}, >- {{0,1,1,0},{1,0,0,1},{0,0,1,1}}, >- {{0,1,1,0},{1,0,1,0},{0,1,1,0}}, >- {{0,1,1,0},{1,0,1,1},{0,0,1,1}}, >- {{0,1,1,0},{1,1,0,0},{0,0,1,0}}, >- {{0,1,1,0},{1,1,0,1},{0,0,1,1}}, >- {{1,0,0,1},{0,0,0,0},{0,0,0,1}}, >- {{1,0,0,1},{0,0,0,1},{0,0,0,1}}, >- {{1,0,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,0,1},{0,1,0,0},{0,0,0,1}}, >- {{1,0,0,1},{0,1,1,0},{0,0,1,1}}, >- {{1,0,0,1},{1,0,0,1},{1,0,0,1}}, >- {{1,0,0,1},{1,0,1,0},{0,0,1,1}}, >- {{1,0,0,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,0,1},{1,1,0,0},{1,1,0,1}}, >- {{1,0,0,1},{1,1,0,1},{1,1,0,1}}, >- {{1,0,1,0},{0,0,0,0},{0,0,1,0}}, >- {{1,0,1,0},{0,0,0,1},{0,0,1,1}}, >- {{1,0,1,0},{0,0,1,0},{0,0,1,0}}, >- {{1,0,1,0},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,0},{0,1,0,0},{0,1,1,0}}, >- {{1,0,1,0},{0,1,1,0},{0,1,1,0}}, >- {{1,0,1,0},{1,0,0,1},{0,0,1,1}}, >- {{1,0,1,0},{1,0,1,0},{1,0,1,0}}, >- {{1,0,1,0},{1,0,1,1},{0,0,1,1}}, >- {{1,0,1,0},{1,1,0,0},{0,0,1,0}}, >- {{1,0,1,0},{1,1,0,1},{0,0,1,1}}, >- {{1,0,1,1},{0,0,0,0},{0,0,0,1}}, >- {{1,0,1,1},{0,0,0,1},{0,0,0,1}}, >- {{1,0,1,1},{0,0,1,0},{0,0,1,1}}, >- {{1,0,1,1},{0,0,1,1},{0,0,1,1}}, >- {{1,0,1,1},{0,1,0,0},{0,0,1,1}}, >- {{1,0,1,1},{0,1,1,0},{0,0,1,1}}, >- {{1,0,1,1},{1,0,0,1},{1,0,1,1}}, >- {{1,0,1,1},{1,0,1,0},{0,0,1,1}}, >- {{1,0,1,1},{1,0,1,1},{1,0,1,1}}, >- {{1,0,1,1},{1,1,0,0},{0,0,0,1}}, >- {{1,0,1,1},{1,1,0,1},{0,0,0,1}}, >- {{1,1,0,0},{0,0,0,0},{0,0,0,0}}, >- {{1,1,0,0},{0,0,0,1},{0,0,0,1}}, >- {{1,1,0,0},{0,0,1,0},{0,0,1,0}}, >- {{1,1,0,0},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,0},{0,1,0,0},{0,0,1,0}}, >- {{1,1,0,0},{0,1,1,0},{0,0,1,0}}, >- {{1,1,0,0},{1,0,0,1},{1,1,0,1}}, >- {{1,1,0,0},{1,0,1,0},{0,0,1,0}}, >- {{1,1,0,0},{1,0,1,1},{0,0,0,1}}, >- {{1,1,0,0},{1,1,0,0},{1,1,0,0}}, >- {{1,1,0,0},{1,1,0,1},{1,1,0,1}}, >- {{1,1,0,1},{0,0,0,0},{0,0,0,1}}, >- {{1,1,0,1},{0,0,0,1},{0,0,0,1}}, >- {{1,1,0,1},{0,0,1,0},{0,0,1,1}}, >- {{1,1,0,1},{0,0,1,1},{0,0,1,1}}, >- {{1,1,0,1},{0,1,0,0},{0,0,1,1}}, >- {{1,1,0,1},{0,1,1,0},{0,0,1,1}}, >- {{1,1,0,1},{1,0,0,1},{1,1,0,1}}, >- {{1,1,0,1},{1,0,1,0},{0,0,1,1}}, >- {{1,1,0,1},{1,0,1,1},{0,0,0,1}}, >- {{1,1,0,1},{1,1,0,0},{1,1,0,1}}, >- {{1,1,0,1},{1,1,0,1},{1,1,0,1}} >- }; >- int failures = 0; >- long start; >- if (combinationTestsloopsNb > 1) { >- start = System.currentTimeMillis(); >- } >- String header = "mergedWith failures: "; >- for (int l = 0; l < combinationTestsloopsNb ; l++) { >- for (int i = 0; i < testData.length; i++) { >- UnconditionalFlowInfoTestHarness result; >- if (!(result = (UnconditionalFlowInfoTestHarness) >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0]). >- mergedWith( >- UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1]))). >- testEquals(UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2]))) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- } >- if (combinationTestsloopsNb > 1) { >- System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" + >- (System.currentTimeMillis() - start)); >- } >- UnconditionalFlowInfoTestHarness >- zero = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(new long[] {0,0,0,0}), >- left1, right1, left2, right2, >- expected1, expected2, result; >- for (int i = 0; i < testData.length; i++) { >- left1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 64); >- left2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][0], 128); >- right1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 64); >- right2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][1], 128); >- expected1 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 64); >- expected2 = UnconditionalFlowInfoTestHarness. >- testUnconditionalFlowInfo(testData[i][2], 128); >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().mergedWith(right1)).testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (testData[i][0][0] + testData[i][0][1] + >- testData[i][0][2] + testData[i][0][3] == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- zero.copy().mergedWith(right1)).testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- right2.copy().mergedWith(right1)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- zero.copy().mergedWith(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero, 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- right1.copy().mergedWith(right2)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (zero 64, 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- if (testData[i][1][0] + testData[i][1][1] + >- testData[i][1][2] + testData[i][1][3] == 0) { >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.copy().mergedWith(zero)).testEquals(expected1)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left1.mergedWith(left2)). >- testEquals(expected1, 64)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left2.copy().mergedWith(zero)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero) - instead of: " + testStringValueOf(testData[i][2])); >- } >- if (!(result = (UnconditionalFlowInfoTestHarness) >- left2.mergedWith(left1)). >- testEquals(expected2, 128)) { >- if (failures == 0) { >- System.out.println(header); >- } >- failures++; >- System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + >- ',' + testStringValueOf(testData[i][1]) + >- ',' + result.testString() + >- "}, // (128, zero 64) - instead of: " + testStringValueOf(testData[i][2])); >- } >- } >- } >- if (printTablesAsNames) { >- System.out.println("RECAP TABLE FOR MERGE"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + >- testSymbolicValueOf(testData[i][1]) + " -> " + >- testSymbolicValueOf(testData[i][2])); >- } >- >- } >- if (printTablesAsCodes) { >- System.out.println("RECAP TABLE FOR MERGE"); >- for (int i = 0; i < testData.length; i++) { >- System.out.println(testCodedValueOf(testData[i][0]) + " " + >- testCodedValueOf(testData[i][1]) + " " + >- testCodedValueOf(testData[i][2])); >- } >- } >- if (printTruthMaps) { >- for (int i = 0; i < 4; i++) { >- System.out.println("======================================================"); >- System.out.println("Truth map for mergedWith null bit " + (i + 1)); >- System.out.println(); >- } >- } >- assertTrue("nb of failures: " + failures, failures == 0); >-} >- >-// Use for coverage tests only. Needs specific instrumentation of code, >-// that is controled by UnconditionalFlowInfo#coverageTestFlag. >-// 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 = 46; >- >-// Coverage by state transition tables methods. >-public void test2998_coverage() { >- if (UnconditionalFlowInfo.coverageTestFlag) { >- // sanity check: need to be sure that the tests execute properly when not >- // trying to check coverage >- UnconditionalFlowInfo.coverageTestId = 0; >- test0053_array(); >- test0070_type_reference(); >- test2050_markAsComparedEqualToNonNull(); >- test2051_markAsComparedEqualToNull(); >- test2052_markAsDefinitelyNonNull(); >- test2053_markAsDefinitelyNull(); >- test2054_markAsDefinitelyUnknown(); >- test2055_addInitializationsFrom(); >- test2056_addPotentialInitializationsFrom(); >- test2057_mergedWith(); >- // coverage check >- int failuresNb = 0; >- for (int i = 1; i <= coveragePointsNb; i++) { >- try { >- UnconditionalFlowInfo.coverageTestId = i; >- test0053_array(); >- test0070_type_reference(); >- test2050_markAsComparedEqualToNonNull(); >- test2051_markAsComparedEqualToNull(); >- test2052_markAsDefinitelyNonNull(); >- test2053_markAsDefinitelyNull(); >- test2054_markAsDefinitelyUnknown(); >- test2055_addInitializationsFrom(); >- test2056_addPotentialInitializationsFrom(); >- test2057_mergedWith(); >- } >- catch (AssertionFailedError e) { >- continue; >- } >- catch (AssertionFailedException e) { >- continue; >- } >- failuresNb++; >- System.out.println("Missing coverage point: " + i); >- } >- UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests >- assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); >- } >-} >- >-// Coverage by code samples. >-public void test2999_coverage() { >- if (UnconditionalFlowInfo.coverageTestFlag) { >- // sanity check: need to be sure that the tests execute properly when not >- // trying to check coverage >- UnconditionalFlowInfo.coverageTestId = 0; >- test0001_simple_local(); >- test0053_array(); >- test0070_type_reference(); >- test0327_if_else(); >- test0401_while(); >- test0420_while(); >- test0509_try_finally_embedded(); >- test2000_flow_info(); >- test2004_flow_info(); >- test2008_flow_info(); >- test2011_flow_info(); >- test2013_flow_info(); >- test2018_flow_info(); >- test2019_flow_info(); >- test2020_flow_info(); >- // coverage check >- int failuresNb = 0; >- for (int i = 1; i <= coveragePointsNb; i++) { >- if (i > 4 && i < 15 || >- i > 15 && i < 19 || >- i == 22 || >- i == 23 || >- i == 27 || >- i == 28 || >- i == 30 || >- i == 33 || >- i == 34 || >- i == 38 || >- i >= 43 >- ) { // TODO (maxime) complete coverage tests >- continue; >- } >- try { >- UnconditionalFlowInfo.coverageTestId = i; >- test0001_simple_local(); >- test0053_array(); >- test0070_type_reference(); >- test0327_if_else(); >- test0401_while(); >- test0420_while(); >- test0509_try_finally_embedded(); >- test2000_flow_info(); >- test2004_flow_info(); >- test2008_flow_info(); >- test2011_flow_info(); >- test2013_flow_info(); >- test2018_flow_info(); >- test2019_flow_info(); >- test2020_flow_info(); >- } >- catch (AssertionFailedError e) { >- continue; >- } >- catch (AssertionFailedException e) { >- continue; >- } >- failuresNb++; >- System.out.println("Missing coverage point: " + i); >- } >- UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests >- assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); >- } >-} >- >-// only works for info coded on bit 0 - least significant >-String testCodedValueOf(long[] data) { >- StringBuffer result = new StringBuffer(4); >- for (int i = 0; i < data.length; i++) { >- result.append(data[i] == 0 ? '0' : '1'); >- } >- return result.toString(); >-} >- >-String testStringValueOf(long[] data) { >- StringBuffer result = new StringBuffer(9); >- result.append('{'); >- for (int j = 0; j < 4; j++) { >- if (j > 0) { >- result.append(','); >- } >- result.append(data[j]); >- } >- result.append('}'); >- return result.toString(); >-} >- >-String testStringValueOf(long[][] data) { >- StringBuffer result = new StringBuffer(25); >- result.append('{'); >- for (int i = 0; i < 3; i++) { >- if (i > 0) { >- result.append(','); >- } >- result.append('{'); >- for (int j = 0; j < 4; j++) { >- if (j > 0) { >- result.append(','); >- } >- result.append(data[i][j]); >- } >- result.append('}'); >- } >- result.append('}'); >- return result.toString(); >-} >- >-// only works for info coded on bit 0 - least significant >-String testSymbolicValueOf(long[] data) { >- if (data[0] == 0) { >- if (data[1] == 0) { >- if (data[2] == 0) { >- if (data[3] == 0) { >- return "start "; //$NON-NLS1$ >- } >- else { >- return "pot. nn/unknown "; //$NON-NLS1$ >- } >- } >- else { >- if (data[3] == 0) { >- return "pot. null "; //$NON-NLS1$ >- } >- else { >- return "pot. n/nn/unkn. "; //$NON-NLS1$ >- } >- } >- } >- else { >- if (data[2] == 0) { >- if (data[3] == 0) { >- return "prot. null "; //$NON-NLS1$ >- } >- else { >- return "0101 "; //$NON-NLS1$ >- } >- } >- else { >- if (data[3] == 0) { >- return "prot. null + pot. null"; //$NON-NLS1$ >- } >- else { >- return "0111 "; //$NON-NLS1$ >- } >- } >- } >- } >- else { >- if (data[1] == 0) { >- if (data[2] == 0) { >- if (data[3] == 0) { >- return "1000 "; //$NON-NLS1$ >- } >- else { >- return "assigned non null "; //$NON-NLS1$ >- } >- } >- else { >- if (data[3] == 0) { >- return "assigned null "; //$NON-NLS1$ >- } >- else { >- return "assigned unknown "; //$NON-NLS1$ >- } >- } >- } >- else { >- if (data[2] == 0) { >- if (data[3] == 0) { >- return "protected non null "; //$NON-NLS1$ >- } >- else { >- return "prot. nn + pot. nn/unknown"; //$NON-NLS1$ >- } >- } >- else { >- if (data[3] == 0) { >- return "1110 "; //$NON-NLS1$ >- } >- else { >- return "1111 "; //$NON-NLS1$ >- } >- } >- } >- } >-} >- >-private void printTruthMap(long data[][][], int bit) { >- final int dimension = 16; >- printTruthMapHeader(); >- char truthValues[][] = new char[dimension][dimension]; >- int row, column; >- for (row = 0; row < dimension; row++) { >- for (column = 0; column < dimension; column++) { >- truthValues[row][column] = '.'; >- } >- } >- String rows[] = { >- "0000", >- "0001", >- "0011", >- "0111", >- "1111", >- "1110", >- "1100", >- "1000", >- "1010", >- "1011", >- "1001", >- "1101", >- "0101", >- "0100", >- "0110", >- "0010" >- }; >- if (false) { // checking row names >- for (row = 0; row < dimension; row++) { >- long [] state = new long [4]; >- for (int i = 0; i < 4; i++) { >- state[i] = rows[row].charAt(i) - '0'; >- } >- System.out.println(row + " " + rows[row] + " " + rankForState(state)); >- } >- } >- for (int i = 0; i < data.length; i++) { >- truthValues[rankForState(data[i][0])][rankForState(data[i][1])] = >- (char) ('0' + data[i][2][bit]); >- } >- for (row = 0; row < dimension; row++) { >- StringBuffer line = new StringBuffer(120); >- line.append(rows[row]); >- line.append(" | "); >- for (column = 0; column < dimension; column++) { >- line.append(truthValues[row][column]); >- line.append(' '); >- } >- System.out.println(line); >- } >-} >- >-private void printTruthMapHeader() { >- System.out.println(" 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0"); >- System.out.println(" 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0"); >- System.out.println(" 0 0 1 1 1 1 0 0 1 1 0 0 0 0 1 1"); >- System.out.println(" 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0"); >- System.out.println(" --------------------------------"); >-} >- >-private int rankForState(long [] state) { >- if (state[0] == 0) { >- if (state[1] == 0) { >- if (state[2] == 0) { >- if (state[3] == 0) { >- return 0; // 0000 >- } >- else { >- return 1; // 0001 >- } >- } >- else { >- if (state[3] == 0) { >- return 15; // 0010 >- } >- else { >- return 2; // 0011 >- } >- } >- } >- else { >- if (state[2] == 0) { >- if (state[3] == 0) { >- return 13; // 0100 >- } >- else { >- return 12; // 0101 >- } >- } >- else { >- if (state[3] == 0) { >- return 14; // 0110 >- } >- else { >- return 3; // 0111 >- } >- } >- } >- } >- else { >- if (state[1] == 0) { >- if (state[2] == 0) { >- if (state[3] == 0) { >- return 7; // 1000 >- } >- else { >- return 10; // 1001 >- } >- } >- else { >- if (state[3] == 0) { >- return 8; // 1010 >- } >- else { >- return 9; // 1011 >- } >- } >- } >- else { >- if (state[2] == 0) { >- if (state[3] == 0) { >- return 6; // 1100 >- } >- else { >- return 11; // 1101 >- } >- } >- else { >- if (state[3] == 0) { >- return 5; // 1110 >- } >- else { >- return 4; // 1111 >- } >- } >- } >- } >-} >-} >- >-class TestLocalVariableBinding extends LocalVariableBinding { >- final static char [] testName = {'t', 'e', 's', 't'}; >- TestLocalVariableBinding(int id) { >- super(testName, null, 0, false); >- this.id = id; >- } >-} >- >-/** >- * A class meant to augment >- * @link{org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo} with >- * capabilities in the test domain. It especially provides factories to build >- * fake flow info instances for use in state transition tables validation. >- */ >-class UnconditionalFlowInfoTestHarness extends UnconditionalFlowInfo { >- private int testPosition; >- >-/** >- * Return a fake unconditional flow info which bit fields represent the given >- * null bits for a local variable of id 0 within a class that would have no >- * field. >- * @param nullBits the bits that must be set, given in the same order as the >- * nullAssignment* fields in UnconditionalFlowInfo definition; use 0 >- * for a bit that is not set, 1 else >- * @return a fake unconditional flow info which bit fields represent the >- * null bits given in parameter >- */ >-public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >- long [] nullBits) { >- return testUnconditionalFlowInfo(nullBits, 0); >-} >- >-public FlowInfo copy() { >- UnconditionalFlowInfoTestHarness copy = >- new UnconditionalFlowInfoTestHarness(); >- copy.testPosition = this.testPosition; >- copy.definiteInits = this.definiteInits; >- copy.potentialInits = this.potentialInits; >- boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0; >- if (hasNullInfo) { >- copy.nullAssignmentStatusBit1 = this.nullAssignmentStatusBit1; >- copy.nullAssignmentStatusBit2 = this.nullAssignmentStatusBit2; >- copy.nullAssignmentValueBit1 = this.nullAssignmentValueBit1; >- copy.nullAssignmentValueBit2 = this.nullAssignmentValueBit2; >- } >- copy.tagBits = this.tagBits; >- copy.maxFieldCount = this.maxFieldCount; >- if (this.extra != null) { >- int length; >- copy.extra = new long[extraLength][]; >- System.arraycopy(this.extra[0], 0, >- (copy.extra[0] = new long[length = extra[0].length]), 0, length); >- System.arraycopy(this.extra[1], 0, >- (copy.extra[1] = new long[length]), 0, length); >- if (hasNullInfo) { >- for (int j = 0; j < extraLength; j++) { >- System.arraycopy(this.extra[j], 0, >- (copy.extra[j] = new long[length]), 0, length); >- } >- } >- else { >- for (int j = 0; j < extraLength; j++) { >- copy.extra[j] = new long[length]; >- } >- } >- } >- return copy; >-} >- >-/** >- * Return a fake unconditional flow info which bit fields represent the given >- * null bits for a local variable of id position within a class that would have >- * no field. >- * @param nullBits the bits that must be set, given in the same order as the >- * nullAssignment* fields in UnconditionalFlowInfo definition; use 0 >- * for a bit that is not set, 1 else >- * @param position the position of the variable within the bit fields; use >- * various values to test different parts of the bit fields, within >- * or beyond BitCacheSize >- * @return a fake unconditional flow info which bit fields represent the >- * null bits given in parameter >- */ >-public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >- long [] nullBits, int position) { >- UnconditionalFlowInfoTestHarness result = >- new UnconditionalFlowInfoTestHarness(); >- result.testPosition = position; >- if (position < BitCacheSize) { >- result.nullAssignmentStatusBit1 = nullBits[0] << position; >- result.nullAssignmentStatusBit2 = nullBits[1] << position; >- result.nullAssignmentValueBit1 = nullBits[2] << position; >- result.nullAssignmentValueBit2 = nullBits[3] << position; >- } >- else { >- int vectorIndex = (position / BitCacheSize) - 1, >- length = vectorIndex + 1; >- position %= BitCacheSize; >- result.extra = new long[extraLength][]; >- result.extra[0] = new long[length]; >- result.extra[1] = new long[length]; >- for (int j = 2; j < extraLength; j++) { >- result.extra[j] = new long[length]; >- result.extra[j][vectorIndex] = nullBits[j - 2] << >- position; >- } >- } >- if ((nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3]) != 0) { >- result.tagBits |= NULL_FLAG_MASK; >- } >- result.maxFieldCount = 0; >- return result; >-} >- >-/** >- * Return a fake unconditional flow info which bit fields represent the given >- * null bits for a pair of local variables of id position and position + >- * extra * BitCacheSize within a class that would have no field. >- * @param nullBits the bits that must be set, given in the same order as the >- * nullAssignment* fields in UnconditionalFlowInfo definition; use 0 >- * for a bit that is not set, 1 else >- * @param position the position of the variable within the bit fields; use >- * various values to test different parts of the bit fields, within >- * or beyond BitCacheSize >- * @param extra the length of the allocated extra bit fields, if position is >- * beyond BitCacheSize; unused otherwise; make sure it is big enough to >- * match position (that is, extra > position - BitCacheSize) >- * @return a fake unconditional flow info which bit fields represent the >- * null bits given in parameter >- */ >-public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >- long [] nullBits, int position, int extra) { >- UnconditionalFlowInfoTestHarness result = >- new UnconditionalFlowInfoTestHarness(); >- result.testPosition = position; >- if (position < BitCacheSize) { >- result.nullAssignmentStatusBit1 = nullBits[0] << position; >- result.nullAssignmentStatusBit2 = nullBits[1] << position; >- result.nullAssignmentValueBit1 = nullBits[2] << position; >- result.nullAssignmentValueBit2 = nullBits[3] << position; >- } >- else { >- int vectorIndex = (position / BitCacheSize) - 1, >- length = extra / BitCacheSize; >- position %= BitCacheSize; >- result.extra = new long[extraLength][]; >- result.extra[0] = new long[length]; >- result.extra[1] = new long[length]; >- for (int j = 2; j < extraLength; j++) { >- result.extra[j] = new long[length]; >- result.extra[j] [vectorIndex]= nullBits[j - 2] << position; >- } >- } >- if (nullBits[1] != 0 || nullBits[3] != 0 || nullBits[0] != 0 || nullBits[2] != 0 ) { >- // cascade better than nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3] >- // by 10%+ >- // TODO (maxime) run stats to determine which is the better order >- result.tagBits |= NULL_FLAG_MASK; >- } >- result.maxFieldCount = 0; >- return result; >-} >- >-/** >- * Return true iff this flow info can be considered as equal to the one passed >- * in parameter. >- * @param other the flow info to compare to >- * @return true iff this flow info compares equal to other >- */ >-public boolean testEquals(UnconditionalFlowInfo other) { >- if (this.tagBits != other.tagBits) { >- return false; >- } >- if (this.nullAssignmentStatusBit1 != other.nullAssignmentStatusBit1 || >- this.nullAssignmentStatusBit2 != other.nullAssignmentStatusBit2 || >- this.nullAssignmentValueBit1 != other.nullAssignmentValueBit1 || >- this.nullAssignmentValueBit2 != other.nullAssignmentValueBit2) { >- return false; >- } >- int left = this.extra == null ? 0 : this.extra[0].length, >- right = other.extra == null ? 0 : other.extra[0].length, >- both = 0, i; >- if (left > right) { >- both = right; >- } >- else { >- both = left; >- } >- for (i = 0; i < both ; i++) { >- if (this.extra[2][i] != >- other.extra[2][i] || >- this.extra[3][i] != >- other.extra[3][i] || >- this.extra[4][i] != >- other.extra[4][i] || >- this.extra[5][i] != >- other.extra[5][i]) { >- return false; >- } >- } >- for (; i < left; i++) { >- if (this.extra[2][i] != 0 || >- this.extra[3][i] != 0 || >- this.extra[4][i] != 0 || >- this.extra[5][i] != 0) { >- return false; >- } >- } >- for (; i < right; i++) { >- if (other.extra[2][i] != 0 || >- other.extra[3][i] != 0 || >- other.extra[4][i] != 0 || >- other.extra[5][i] != 0) { >- return false; >- } >- } >- return true; >-} >- >-/** >- * Return true iff this flow info can be considered as equal to the one passed >- * in parameter in respect with a single local variable which id would be >- * position in a class with no field. >- * @param other the flow info to compare to >- * @param position the position of the local to consider >- * @return true iff this flow info compares equal to other for a given local >- */ >-public boolean testEquals(UnconditionalFlowInfo other, int position) { >- int vectorIndex = position / BitCacheSize - 1; >- if ((this.tagBits & other.tagBits & NULL_FLAG_MASK) == 0) { >- return true; >- } >- long mask; >- if (vectorIndex < 0) { >- return ((this.nullAssignmentStatusBit1 & (mask = (1L << position))) ^ >- (other.nullAssignmentStatusBit1 & mask)) == 0 && >- ((this.nullAssignmentStatusBit2 & mask) ^ >- (other.nullAssignmentStatusBit2 & mask)) == 0 && >- ((this.nullAssignmentValueBit1 & mask) ^ >- (other.nullAssignmentValueBit1 & mask)) == 0 && >- ((this.nullAssignmentValueBit2 & mask) ^ >- (other.nullAssignmentValueBit2 & mask)) == 0; >- } >- else { >- int left = this.extra == null ? >- 0 : >- this.extra[0].length; >- int right = other.extra == null ? >- 0 : >- other.extra[0].length; >- int both = left < right ? left : right; >- if (vectorIndex < both) { >- return ((this.extra[2][vectorIndex] & >- (mask = (1L << (position % BitCacheSize)))) ^ >- (other.extra[2][vectorIndex] & mask)) == 0 && >- ((this.extra[3][vectorIndex] & mask) ^ >- (other.extra[3][vectorIndex] & mask)) == 0 && >- ((this.extra[4][vectorIndex] & mask) ^ >- (other.extra[4][vectorIndex] & mask)) == 0 && >- ((this.extra[5][vectorIndex] & mask) ^ >- (other.extra[5][vectorIndex] & mask)) == 0; >- } >- if (vectorIndex < left) { >- return ((this.extra[2][vectorIndex] | >- this.extra[3][vectorIndex] | >- this.extra[4][vectorIndex] | >- this.extra[5][vectorIndex]) & >- (1L << (position % BitCacheSize))) == 0; >- } >- return ((other.extra[2][vectorIndex] | >- other.extra[3][vectorIndex] | >- other.extra[4][vectorIndex] | >- other.extra[5][vectorIndex]) & >- (1L << (position % BitCacheSize))) == 0; >- } >-} >- >-/** >- * Return a string suitable for use as a representation of this flow info >- * within test series. >- * @return a string suitable for use as a representation of this flow info >- */ >-public String testString() { >- if (this == DEAD_END) { >- return "FlowInfo.DEAD_END"; //$NON-NLS-1$ >- } >- return testString(this.testPosition); >-} >- >-/** >- * Return a string suitable for use as a representation of this flow info >- * within test series. >- * @param position a position to consider instead of this flow info default >- * test position >- * @return a string suitable for use as a representation of this flow info >- */ >-public String testString(int position) { >- if (this == DEAD_END) { >- return "FlowInfo.DEAD_END"; //$NON-NLS-1$ >- } >- if (position < BitCacheSize) { >- return "{" + (this.nullAssignmentStatusBit1 >> position) //$NON-NLS-1$ >- + "," + (this.nullAssignmentStatusBit2 >> position) //$NON-NLS-1$ >- + "," + (this.nullAssignmentValueBit1 >> position) //$NON-NLS-1$ >- + "," + (this.nullAssignmentValueBit2 >> position) //$NON-NLS-1$ >- + "}"; //$NON-NLS-1$ >- } >- else { >- int vectorIndex = position / BitCacheSize - 1, >- shift = position % BitCacheSize; >- return "{" + (this.extra[2][vectorIndex] //$NON-NLS-1$ >- >> shift) >- + "," + (this.extra[3][vectorIndex] //$NON-NLS-1$ >- >> shift) >- + "," + (this.extra[4][vectorIndex] //$NON-NLS-1$ >- >> shift) >- + "," + (this.extra[5][vectorIndex] //$NON-NLS-1$ >- >> shift) >- + "}"; //$NON-NLS-1$ >- } >-} > } >Index: .settings/org.eclipse.jdt.ui.prefs >=================================================================== >RCS file: .settings/org.eclipse.jdt.ui.prefs >diff -N .settings/org.eclipse.jdt.ui.prefs >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ .settings/org.eclipse.jdt.ui.prefs 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,5 @@ >+#Thu Feb 23 14:36:02 CET 2006 >+eclipse.preferences.version=1 >+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile >+formatter_settings_version=10 >+internal.default.compliance=user >Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java >=================================================================== >RCS file: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java >diff -N src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,3177 @@ >+/******************************************************************************* >+ * Copyright (c) 2005 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+import java.io.BufferedReader; >+import java.io.BufferedWriter; >+import java.io.File; >+import java.io.FileOutputStream; >+import java.io.IOException; >+import java.io.PrintWriter; >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.Map; >+import java.util.SortedMap; >+import java.util.TreeMap; >+ >+import org.eclipse.jdt.core.tests.compiler.regression.NullReferenceImplTests.State; >+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; >+public class NullReferenceImplTransformations { >+ public static final Transformation >+ markAsComparedEqualToNonNull = >+ // markAsComparedEqualToNonNull DEFINITION START >+ // start => prot. non null >+ // prot. non null => prot. non null >+ // prot. null => prot. non null >+ // pot. unknown => pot. nn & prot. nn >+ // pot. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. nn & pot. un => pot. nn & prot. nn >+ // pot. null => prot. non null >+ // pot. n & prot. n => prot. non null >+ // pot. n & pot. un => pot. nn & prot. nn >+ // pot. n & pot. nn => pot. nn & prot. nn >+ // def. unknown => def. non null >+ // def. non null => def. non null >+ // def. null => prot. non null >+ // markAsComparedEqualToNonNull DEFINITION END >+ new TwoDimensionalTransformation("markAsComparedEqualToNonNull", >+ new byte[][] { >+ // markAsComparedEqualToNonNull INITIALIZER START >+ {0x00,0x3C}, >+ {0x04,0x2C}, >+ {0x08,0x2C}, >+ {0x0C,0x2C}, >+ {0x10,0x3C}, >+ {0x14,0x2C}, >+ {0x18,0x2C}, >+ {0x24,0x28}, >+ {0x28,0x28}, >+ {0x2C,0x2C}, >+ {0x30,0x3C}, >+ {0x34,0x3C}, >+ {0x38,0x3C}, >+ {0x3C,0x3C}, >+ // markAsComparedEqualToNonNull INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input, >+ TestLocalVariableBinding local) { >+ UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy(); >+ result.markAsComparedEqualToNonNull(local); >+ return result; >+ } >+ }, >+ markAsComparedEqualToNull = >+ // markAsComparedEqualToNull DEFINITION START >+ // start => prot. null >+ // prot. non null => prot. null >+ // prot. null => prot. null >+ // pot. unknown => pot. n & prot. n >+ // pot. non null => prot. null >+ // pot. nn & prot. nn => prot. null >+ // pot. nn & pot. un => pot. n & prot. n >+ // pot. null => pot. n & prot. n >+ // pot. n & prot. n => pot. n & prot. n >+ // pot. n & pot. un => pot. n & prot. n >+ // pot. n & pot. nn => pot. n & prot. n >+ // def. unknown => def. null >+ // def. non null => prot. null >+ // def. null => def. null >+ // markAsComparedEqualToNull DEFINITION END >+ new TwoDimensionalTransformation("markAsComparedEqualToNull", >+ new byte[][] { >+ // markAsComparedEqualToNull INITIALIZER START >+ {0x00,0x38}, >+ {0x04,0x34}, >+ {0x08,0x38}, >+ {0x0C,0x34}, >+ {0x10,0x34}, >+ {0x14,0x34}, >+ {0x18,0x34}, >+ {0x24,0x30}, >+ {0x28,0x38}, >+ {0x2C,0x38}, >+ {0x30,0x30}, >+ {0x34,0x34}, >+ {0x38,0x38}, >+ {0x3C,0x38}, >+ // markAsComparedEqualToNull INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input, >+ TestLocalVariableBinding local) { >+ UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy(); >+ result.markAsComparedEqualToNull(local); >+ return result; >+ } >+ }, >+ markAsDefinitelyNonNull = >+ // markAsDefinitelyNonNull DEFINITION START >+ // start => def. non null >+ // prot. non null => def. non null >+ // prot. null => def. non null >+ // pot. unknown => def. non null >+ // pot. non null => def. non null >+ // pot. nn & prot. nn => def. non null >+ // pot. nn & pot. un => def. non null >+ // pot. null => def. non null >+ // pot. n & prot. n => def. non null >+ // pot. n & pot. un => def. non null >+ // pot. n & pot. nn => def. non null >+ // def. unknown => def. non null >+ // def. non null => def. non null >+ // def. null => def. non null >+ // markAsDefinitelyNonNull DEFINITION END >+ new TwoDimensionalTransformation("markAsDefinitelyNonNull", >+ new byte[][] { >+ // markAsDefinitelyNonNull INITIALIZER START >+ {0x00,0x28}, >+ {0x04,0x28}, >+ {0x08,0x28}, >+ {0x0C,0x28}, >+ {0x10,0x28}, >+ {0x14,0x28}, >+ {0x18,0x28}, >+ {0x24,0x28}, >+ {0x28,0x28}, >+ {0x2C,0x28}, >+ {0x30,0x28}, >+ {0x34,0x28}, >+ {0x38,0x28}, >+ {0x3C,0x28}, >+ // markAsDefinitelyNonNull INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input, >+ TestLocalVariableBinding local) { >+ UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy(); >+ result.markAsDefinitelyNonNull(local); >+ return result; >+ } >+ }, >+ markAsDefinitelyNull = >+ // markAsDefinitelyNull DEFINITION START >+ // start => def. null >+ // prot. non null => def. null >+ // prot. null => def. null >+ // pot. unknown => def. null >+ // pot. non null => def. null >+ // pot. nn & prot. nn => def. null >+ // pot. nn & pot. un => def. null >+ // pot. null => def. null >+ // pot. n & prot. n => def. null >+ // pot. n & pot. un => def. null >+ // pot. n & pot. nn => def. null >+ // def. unknown => def. null >+ // def. non null => def. null >+ // def. null => def. null >+ // markAsDefinitelyNull DEFINITION END >+ // PREMATURE add 'catch rules' >+ new TwoDimensionalTransformation("markAsDefinitelyNull", >+ new byte[][] { >+ // markAsDefinitelyNull INITIALIZER START >+ {0x00,0x30}, >+ {0x04,0x30}, >+ {0x08,0x30}, >+ {0x0C,0x30}, >+ {0x10,0x30}, >+ {0x14,0x30}, >+ {0x18,0x30}, >+ {0x24,0x30}, >+ {0x28,0x30}, >+ {0x2C,0x30}, >+ {0x30,0x30}, >+ {0x34,0x30}, >+ {0x38,0x30}, >+ {0x3C,0x30}, >+ // markAsDefinitelyNull INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input, >+ TestLocalVariableBinding local) { >+ UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy(); >+ result.markAsDefinitelyNull(local); >+ return result; >+ } >+ }, >+ markAsDefinitelyUnknown = >+ // markAsDefinitelyUnknown DEFINITION START >+ // start => def. unknown >+ // prot. non null => def. unknown >+ // prot. null => def. unknown >+ // pot. unknown => def. unknown >+ // pot. non null => def. unknown >+ // pot. nn & prot. nn => def. unknown >+ // pot. nn & pot. un => def. unknown >+ // pot. null => def. unknown >+ // pot. n & prot. n => def. unknown >+ // pot. n & pot. un => def. unknown >+ // pot. n & pot. nn => def. unknown >+ // def. unknown => def. unknown >+ // def. non null => def. unknown >+ // def. null => def. unknown >+ // markAsDefinitelyUnknown DEFINITION END >+ new TwoDimensionalTransformation("markAsDefinitelyUnknown", >+ new byte[][] { >+ // markAsDefinitelyUnknown INITIALIZER START >+ {0x00,0x24}, >+ {0x04,0x24}, >+ {0x08,0x24}, >+ {0x0C,0x24}, >+ {0x10,0x24}, >+ {0x14,0x24}, >+ {0x18,0x24}, >+ {0x24,0x24}, >+ {0x28,0x24}, >+ {0x2C,0x24}, >+ {0x30,0x24}, >+ {0x34,0x24}, >+ {0x38,0x24}, >+ {0x3C,0x24}, >+ // markAsDefinitelyUnknown INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input, >+ TestLocalVariableBinding local) { >+ UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy(); >+ result.markAsDefinitelyUnknown(local); >+ return result; >+ } >+ }, >+ addInitializationsFrom = >+ // addInitializationsFrom DEFINITION START >+ // def. non null + def. non null => def. non null >+ // def. non null + def. null => def. null >+ // def. non null + def. unknown => def. unknown >+ // def. non null + pot. n & pot. nn => pot. n & pot. nn >+ // def. non null + pot. n & pot. un => pot. n & pot. nn >+ // def. non null + pot. n & prot. n => pot. n & prot. n >+ // def. non null + pot. nn & pot. un => def. unknown >+ // def. non null + pot. nn & prot. nn => def. non null >+ // def. non null + pot. non null => def. non null >+ // def. non null + pot. null => pot. n & pot. nn >+ // def. non null + pot. unknown => def. unknown // priv. >+ // def. non null + prot. non null => def. non null >+ // def. non null + prot. null => prot. null >+ // def. non null + start => def. non null >+ // def. null + def. non null => def. non null >+ // def. null + def. null => def. null >+ // def. null + def. unknown => def. unknown >+ // def. null + pot. n & pot. nn => pot. n & pot. nn >+ // def. null + pot. n & pot. un => pot. n & pot. un >+ // def. null + pot. n & prot. n => def. null >+ // def. null + pot. nn & pot. un => pot. n & pot. nn >+ // def. null + pot. nn & prot. nn => pot. nn & prot. nn >+ // def. null + pot. non null => pot. n & pot. nn >+ // def. null + pot. null => def. null >+ // def. null + pot. unknown => pot. n & pot. un // pot. null privileged over def. unknown >+ // def. null + prot. non null => prot. non null >+ // def. null + prot. null => def. null >+ // def. null + start => def. null >+ // def. unknown + def. non null => def. non null >+ // def. unknown + def. null => def. null >+ // def. unknown + def. unknown => def. unknown >+ // def. unknown + pot. n & pot. nn => pot. n & pot. nn >+ // def. unknown + pot. n & pot. un => pot. n & pot. un // we loose the def here, but we need the pot. null >+ // def. unknown + pot. n & prot. n => def. null >+ // def. unknown + pot. nn & pot. un => def. unknown // priv. >+ // def. unknown + pot. nn & prot. nn => def. non null >+ // def. unknown + pot. non null => def. unknown // privileging over pot. nn & pot. un >+ // def. unknown + pot. null => pot. n & pot. un >+ // def. unknown + pot. unknown => def. unknown >+ // def. unknown + prot. non null => def. non null >+ // def. unknown + prot. null => def. null >+ // def. unknown + start => def. unknown >+ // pot. n & pot. nn + def. non null => def. non null >+ // pot. n & pot. nn + def. null => def. null >+ // pot. n & pot. nn + def. unknown => def. unknown >+ // pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & prot. n => pot. n & prot. n >+ // pot. n & pot. nn + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & pot. nn + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. n & pot. nn + pot. non null => pot. n & pot. nn >+ // pot. n & pot. nn + pot. null => pot. n & pot. nn >+ // pot. n & pot. nn + pot. unknown => pot. n & pot. nn >+ // pot. n & pot. nn + prot. non null => pot. nn & prot. nn >+ // pot. n & pot. nn + prot. null => pot. n & prot. n >+ // pot. n & pot. nn + start => pot. n & pot. nn >+ // pot. n & pot. un + def. non null => def. non null >+ // pot. n & pot. un + def. null => def. null >+ // pot. n & pot. un + def. unknown => def. unknown >+ // pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. un + pot. n & pot. un => pot. n & pot. un >+ // pot. n & pot. un + pot. n & prot. n => pot. n & prot. n >+ // pot. n & pot. un + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & pot. un + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. n & pot. un + pot. non null => pot. n & pot. nn >+ // pot. n & pot. un + pot. null => pot. n & pot. un >+ // pot. n & pot. un + pot. unknown => pot. n & pot. un >+ // pot. n & pot. un + prot. non null => pot. nn & prot. nn >+ // pot. n & pot. un + prot. null => pot. n & prot. n >+ // pot. n & pot. un + start => pot. n & pot. un >+ // pot. n & prot. n + def. non null => def. non null >+ // pot. n & prot. n + def. null => def. null >+ // pot. n & prot. n + def. unknown => def. unknown >+ // pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & prot. n + pot. n & pot. un => pot. n & pot. un >+ // pot. n & prot. n + pot. n & prot. n => pot. n & prot. n >+ // pot. n & prot. n + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & prot. n + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. n & prot. n + pot. non null => pot. n & pot. nn >+ // pot. n & prot. n + pot. null => pot. n & prot. n >+ // pot. n & prot. n + pot. unknown => pot. n & pot. un >+ // pot. n & prot. n + prot. non null => prot. non null >+ // pot. n & prot. n + prot. null => pot. n & prot. n >+ // pot. n & prot. n + start => pot. n & prot. n >+ // pot. nn & pot. un + def. non null => def. non null >+ // pot. nn & pot. un + def. null => def. null >+ // pot. nn & pot. un + def. unknown => def. unknown >+ // pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & prot. n => pot. n & prot. n >+ // pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un >+ // pot. nn & pot. un + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. nn & pot. un + pot. non null => pot. nn & pot. un >+ // pot. nn & pot. un + pot. null => pot. n & pot. nn >+ // pot. nn & pot. un + pot. unknown => pot. nn & pot. un >+ // pot. nn & pot. un + prot. non null => pot. nn & prot. nn >+ // pot. nn & pot. un + prot. null => pot. n & prot. n >+ // pot. nn & pot. un + start => pot. nn & pot. un >+ // pot. nn & prot. nn + def. non null => def. non null >+ // pot. nn & prot. nn + def. null => def. null >+ // pot. nn & prot. nn + def. unknown => def. unknown >+ // pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & prot. n => pot. n & prot. n >+ // pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un >+ // pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. nn & prot. nn + pot. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + pot. null => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. unknown => pot. nn & pot. un >+ // pot. nn & prot. nn + prot. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + prot. null => prot. null >+ // pot. nn & prot. nn + start => pot. nn & prot. nn >+ // pot. non null + def. non null => def. non null >+ // pot. non null + def. null => def. null >+ // pot. non null + def. unknown => def. unknown >+ // pot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. non null + pot. n & pot. un => pot. n & pot. nn >+ // pot. non null + pot. n & prot. n => pot. n & prot. n >+ // pot. non null + pot. nn & pot. un => pot. nn & pot. un >+ // pot. non null + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. non null + pot. non null => pot. non null >+ // pot. non null + pot. null => pot. n & pot. nn >+ // pot. non null + pot. unknown => pot. nn & pot. un >+ // pot. non null + prot. non null => pot. nn & prot. nn >+ // pot. non null + prot. null => prot. null >+ // pot. non null + start => pot. non null >+ // pot. null + def. non null => def. non null >+ // pot. null + def. null => def. null >+ // pot. null + def. unknown => def. unknown >+ // pot. null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. null + pot. n & pot. un => pot. n & pot. un >+ // pot. null + pot. n & prot. n => pot. n & prot. n >+ // pot. null + pot. nn & pot. un => pot. n & pot. nn >+ // pot. null + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. null + pot. non null => pot. n & pot. nn >+ // pot. null + pot. null => pot. null >+ // pot. null + pot. unknown => pot. n & pot. un >+ // pot. null + prot. non null => prot. non null >+ // pot. null + prot. null => pot. n & prot. n >+ // pot. null + start => pot. null >+ // pot. unknown + def. non null => def. non null >+ // pot. unknown + def. null => def. null >+ // pot. unknown + def. unknown => def. unknown >+ // pot. unknown + pot. n & pot. nn => pot. n & pot. nn >+ // pot. unknown + pot. n & pot. un => pot. n & pot. un >+ // pot. unknown + pot. n & prot. n => pot. n & prot. n >+ // pot. unknown + pot. nn & pot. un => pot. nn & pot. un >+ // pot. unknown + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. unknown + pot. non null => pot. nn & pot. un >+ // pot. unknown + pot. null => pot. n & pot. un >+ // pot. unknown + pot. unknown => pot. unknown >+ // pot. unknown + prot. non null => pot. nn & prot. nn >+ // pot. unknown + prot. null => pot. n & prot. n >+ // pot. unknown + start => pot. unknown >+ // prot. non null + def. non null => def. non null >+ // prot. non null + def. null => def. null >+ // prot. non null + def. unknown => def. unknown >+ // prot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. non null + pot. n & pot. un => pot. n & pot. un >+ // prot. non null + pot. n & prot. n => pot. n & prot. n >+ // prot. non null + pot. nn & pot. un => pot. nn & pot. un >+ // prot. non null + pot. nn & prot. nn => pot. nn & prot. nn >+ // prot. non null + pot. non null => pot. nn & prot. nn >+ // prot. non null + pot. null => pot. null >+ // prot. non null + pot. unknown => pot. unknown >+ // prot. non null + prot. non null => prot. non null >+ // prot. non null + prot. null => prot. null >+ // prot. non null + start => prot. non null >+ // prot. null + def. non null => def. non null >+ // prot. null + def. null => def. null >+ // prot. null + def. unknown => def. unknown >+ // prot. null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. null + pot. n & pot. un => pot. n & pot. un >+ // prot. null + pot. n & prot. n => pot. n & prot. n >+ // prot. null + pot. nn & pot. un => pot. nn & pot. un >+ // prot. null + pot. nn & prot. nn => pot. nn & prot. nn >+ // prot. null + pot. non null => pot. non null >+ // prot. null + pot. null => pot. n & prot. n >+ // prot. null + pot. unknown => pot. unknown >+ // prot. null + prot. non null => prot. non null >+ // prot. null + prot. null => prot. null >+ // prot. null + start => prot. null >+ // start + def. non null => def. non null >+ // start + def. null => def. null >+ // start + def. unknown => def. unknown >+ // start + pot. n & pot. nn => pot. n & pot. nn >+ // start + pot. n & pot. un => pot. n & pot. un >+ // start + pot. n & prot. n => pot. n & prot. n >+ // start + pot. nn & pot. un => pot. nn & pot. un >+ // start + pot. nn & prot. nn => pot. nn & prot. nn >+ // start + pot. non null => pot. non null >+ // start + pot. null => pot. null >+ // start + pot. unknown => pot. unknown >+ // start + prot. non null => prot. non null >+ // start + prot. null => prot. null >+ // start + start => start >+ // addInitializationsFrom DEFINITION END >+ new ThreeDimensionalTransformation("addInitializationsFrom", >+ new byte[][] { >+ // addInitializationsFrom INITIALIZER START >+ {0x00,0x00,0x00}, >+ {0x00,0x04,0x04}, >+ {0x00,0x08,0x08}, >+ {0x00,0x0C,0x0C}, >+ {0x00,0x10,0x10}, >+ {0x00,0x14,0x14}, >+ {0x00,0x18,0x18}, >+ {0x00,0x24,0x24}, >+ {0x00,0x28,0x28}, >+ {0x00,0x2C,0x2C}, >+ {0x00,0x30,0x30}, >+ {0x00,0x34,0x34}, >+ {0x00,0x38,0x38}, >+ {0x00,0x3C,0x3C}, >+ {0x04,0x00,0x04}, >+ {0x04,0x04,0x04}, >+ {0x04,0x08,0x0C}, >+ {0x04,0x0C,0x0C}, >+ {0x04,0x10,0x14}, >+ {0x04,0x14,0x14}, >+ {0x04,0x18,0x18}, >+ {0x04,0x24,0x24}, >+ {0x04,0x28,0x28}, >+ {0x04,0x2C,0x2C}, >+ {0x04,0x30,0x30}, >+ {0x04,0x34,0x34}, >+ {0x04,0x38,0x34}, >+ {0x04,0x3C,0x2C}, >+ {0x08,0x00,0x08}, >+ {0x08,0x04,0x0C}, >+ {0x08,0x08,0x08}, >+ {0x08,0x0C,0x0C}, >+ {0x08,0x10,0x18}, >+ {0x08,0x14,0x18}, >+ {0x08,0x18,0x18}, >+ {0x08,0x24,0x24}, >+ {0x08,0x28,0x28}, >+ {0x08,0x2C,0x2C}, >+ {0x08,0x30,0x30}, >+ {0x08,0x34,0x34}, >+ {0x08,0x38,0x38}, >+ {0x08,0x3C,0x2C}, >+ {0x0C,0x00,0x0C}, >+ {0x0C,0x04,0x0C}, >+ {0x0C,0x08,0x0C}, >+ {0x0C,0x0C,0x0C}, >+ {0x0C,0x10,0x18}, >+ {0x0C,0x14,0x18}, >+ {0x0C,0x18,0x18}, >+ {0x0C,0x24,0x24}, >+ {0x0C,0x28,0x28}, >+ {0x0C,0x2C,0x2C}, >+ {0x0C,0x30,0x30}, >+ {0x0C,0x34,0x34}, >+ {0x0C,0x38,0x34}, >+ {0x0C,0x3C,0x2C}, >+ {0x10,0x00,0x10}, >+ {0x10,0x04,0x14}, >+ {0x10,0x08,0x18}, >+ {0x10,0x0C,0x18}, >+ {0x10,0x10,0x10}, >+ {0x10,0x14,0x14}, >+ {0x10,0x18,0x18}, >+ {0x10,0x24,0x24}, >+ {0x10,0x28,0x28}, >+ {0x10,0x2C,0x2C}, >+ {0x10,0x30,0x30}, >+ {0x10,0x34,0x34}, >+ {0x10,0x38,0x34}, >+ {0x10,0x3C,0x3C}, >+ {0x14,0x00,0x14}, >+ {0x14,0x04,0x14}, >+ {0x14,0x08,0x18}, >+ {0x14,0x0C,0x18}, >+ {0x14,0x10,0x14}, >+ {0x14,0x14,0x14}, >+ {0x14,0x18,0x18}, >+ {0x14,0x24,0x24}, >+ {0x14,0x28,0x28}, >+ {0x14,0x2C,0x2C}, >+ {0x14,0x30,0x30}, >+ {0x14,0x34,0x34}, >+ {0x14,0x38,0x34}, >+ {0x14,0x3C,0x2C}, >+ {0x18,0x00,0x18}, >+ {0x18,0x04,0x18}, >+ {0x18,0x08,0x18}, >+ {0x18,0x0C,0x18}, >+ {0x18,0x10,0x18}, >+ {0x18,0x14,0x18}, >+ {0x18,0x18,0x18}, >+ {0x18,0x24,0x24}, >+ {0x18,0x28,0x28}, >+ {0x18,0x2C,0x2C}, >+ {0x18,0x30,0x30}, >+ {0x18,0x34,0x34}, >+ {0x18,0x38,0x34}, >+ {0x18,0x3C,0x2C}, >+ {0x24,0x00,0x24}, >+ {0x24,0x04,0x24}, >+ {0x24,0x08,0x24}, >+ {0x24,0x0C,0x24}, >+ {0x24,0x10,0x14}, >+ {0x24,0x14,0x14}, >+ {0x24,0x18,0x18}, >+ {0x24,0x24,0x24}, >+ {0x24,0x28,0x28}, >+ {0x24,0x2C,0x28}, >+ {0x24,0x30,0x30}, >+ {0x24,0x34,0x30}, >+ {0x24,0x38,0x30}, >+ {0x24,0x3C,0x28}, >+ {0x28,0x00,0x28}, >+ {0x28,0x04,0x24}, >+ {0x28,0x08,0x28}, >+ {0x28,0x0C,0x24}, >+ {0x28,0x10,0x18}, >+ {0x28,0x14,0x18}, >+ {0x28,0x18,0x18}, >+ {0x28,0x24,0x24}, >+ {0x28,0x28,0x28}, >+ {0x28,0x2C,0x28}, >+ {0x28,0x30,0x30}, >+ {0x28,0x34,0x34}, >+ {0x28,0x38,0x38}, >+ {0x28,0x3C,0x28}, >+ {0x2C,0x00,0x2C}, >+ {0x2C,0x04,0x0C}, >+ {0x2C,0x08,0x2C}, >+ {0x2C,0x0C,0x0C}, >+ {0x2C,0x10,0x18}, >+ {0x2C,0x14,0x18}, >+ {0x2C,0x18,0x18}, >+ {0x2C,0x24,0x24}, >+ {0x2C,0x28,0x28}, >+ {0x2C,0x2C,0x2C}, >+ {0x2C,0x30,0x30}, >+ {0x2C,0x34,0x34}, >+ {0x2C,0x38,0x38}, >+ {0x2C,0x3C,0x2C}, >+ {0x30,0x00,0x30}, >+ {0x30,0x04,0x14}, >+ {0x30,0x08,0x18}, >+ {0x30,0x0C,0x18}, >+ {0x30,0x10,0x30}, >+ {0x30,0x14,0x14}, >+ {0x30,0x18,0x18}, >+ {0x30,0x24,0x24}, >+ {0x30,0x28,0x28}, >+ {0x30,0x2C,0x2C}, >+ {0x30,0x30,0x30}, >+ {0x30,0x34,0x30}, >+ {0x30,0x38,0x30}, >+ {0x30,0x3C,0x3C}, >+ {0x34,0x00,0x34}, >+ {0x34,0x04,0x14}, >+ {0x34,0x08,0x18}, >+ {0x34,0x0C,0x18}, >+ {0x34,0x10,0x34}, >+ {0x34,0x14,0x14}, >+ {0x34,0x18,0x18}, >+ {0x34,0x24,0x24}, >+ {0x34,0x28,0x28}, >+ {0x34,0x2C,0x2C}, >+ {0x34,0x30,0x30}, >+ {0x34,0x34,0x34}, >+ {0x34,0x38,0x34}, >+ {0x34,0x3C,0x3C}, >+ {0x38,0x00,0x38}, >+ {0x38,0x04,0x04}, >+ {0x38,0x08,0x08}, >+ {0x38,0x0C,0x0C}, >+ {0x38,0x10,0x34}, >+ {0x38,0x14,0x14}, >+ {0x38,0x18,0x18}, >+ {0x38,0x24,0x24}, >+ {0x38,0x28,0x28}, >+ {0x38,0x2C,0x2C}, >+ {0x38,0x30,0x30}, >+ {0x38,0x34,0x34}, >+ {0x38,0x38,0x38}, >+ {0x38,0x3C,0x3C}, >+ {0x3C,0x00,0x3C}, >+ {0x3C,0x04,0x04}, >+ {0x3C,0x08,0x2C}, >+ {0x3C,0x0C,0x0C}, >+ {0x3C,0x10,0x10}, >+ {0x3C,0x14,0x14}, >+ {0x3C,0x18,0x18}, >+ {0x3C,0x24,0x24}, >+ {0x3C,0x28,0x28}, >+ {0x3C,0x2C,0x2C}, >+ {0x3C,0x30,0x30}, >+ {0x3C,0x34,0x34}, >+ {0x3C,0x38,0x38}, >+ {0x3C,0x3C,0x3C}, >+ // addInitializationsFrom INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input1, >+ UnconditionalFlowInfo input2) { >+ return (UnconditionalFlowInfo) >+ input1.copy().addInitializationsFrom(input2); >+ } >+ }, >+ // addPotentialInitializationsFrom DEFINITION START >+ // def. non null + def. non null => def. non null >+ // def. non null + def. null => pot. n & pot. nn >+ // def. non null + def. unknown => def. unknown >+ // def. non null + pot. n & pot. nn => pot. n & pot. nn >+ // def. non null + pot. n & pot. un => pot. n & pot. nn >+ // def. non null + pot. n & prot. n => pot. n & pot. nn >+ // def. non null + pot. nn & pot. un => def. unknown >+ // def. non null + pot. nn & prot. nn => def. non null >+ // def. non null + pot. non null => def. non null >+ // def. non null + pot. null => pot. n & pot. nn >+ // def. non null + pot. unknown => def. unknown >+ // def. non null + prot. non null => def. non null >+ // def. non null + prot. null => def. non null >+ // def. non null + start => def. non null >+ // def. null + def. non null => pot. n & pot. nn >+ // def. null + def. null => def. null >+ // def. null + def. unknown => pot. n & pot. un >+ // def. null + pot. n & pot. nn => pot. n & pot. nn >+ // def. null + pot. n & pot. un => pot. n & pot. un >+ // def. null + pot. n & prot. n => def. null >+ // def. null + pot. nn & pot. un => pot. n & pot. nn >+ // def. null + pot. nn & prot. nn => pot. n & pot. nn >+ // def. null + pot. non null => pot. n & pot. nn >+ // def. null + pot. null => def. null >+ // def. null + pot. unknown => pot. n & pot. un >+ // def. null + prot. non null => def. null >+ // def. null + prot. null => def. null >+ // def. null + start => def. null >+ // def. unknown + def. non null => def. unknown >+ // def. unknown + def. null => pot. n & pot. un >+ // def. unknown + def. unknown => def. unknown >+ // def. unknown + pot. n & pot. nn => pot. n & pot. nn >+ // def. unknown + pot. n & pot. un => pot. n & pot. un >+ // def. unknown + pot. n & prot. n => pot. n & pot. un >+ // def. unknown + pot. nn & pot. un => def. unknown >+ // def. unknown + pot. nn & prot. nn => def. unknown >+ // def. unknown + pot. non null => def. unknown >+ // def. unknown + pot. null => pot. n & pot. un >+ // def. unknown + pot. unknown => def. unknown >+ // def. unknown + prot. non null => def. unknown >+ // def. unknown + prot. null => def. unknown >+ // def. unknown + start => def. unknown >+ // pot. n & pot. nn + def. non null => pot. n & pot. nn >+ // pot. n & pot. nn + def. null => pot. n & pot. nn >+ // pot. n & pot. nn + def. unknown => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & prot. n => pot. n & pot. nn >+ // pot. n & pot. nn + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & pot. nn + pot. nn & prot. nn => pot. n & pot. nn >+ // pot. n & pot. nn + pot. non null => pot. n & pot. nn >+ // pot. n & pot. nn + pot. null => pot. n & pot. nn >+ // pot. n & pot. nn + pot. unknown => pot. n & pot. nn >+ // pot. n & pot. nn + prot. non null => pot. n & pot. nn >+ // pot. n & pot. nn + prot. null => pot. n & pot. nn >+ // pot. n & pot. nn + start => pot. n & pot. nn >+ // pot. n & pot. un + def. non null => pot. n & pot. nn >+ // pot. n & pot. un + def. null => pot. n & pot. un >+ // pot. n & pot. un + def. unknown => pot. n & pot. un >+ // pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. un + pot. n & pot. un => pot. n & pot. un >+ // pot. n & pot. un + pot. n & prot. n => pot. n & pot. un >+ // pot. n & pot. un + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & pot. un + pot. nn & prot. nn => pot. n & pot. nn >+ // pot. n & pot. un + pot. non null => pot. n & pot. nn >+ // pot. n & pot. un + pot. null => pot. n & pot. un >+ // pot. n & pot. un + pot. unknown => pot. n & pot. un >+ // pot. n & pot. un + prot. non null => pot. n & pot. un >+ // pot. n & pot. un + prot. null => pot. n & pot. un >+ // pot. n & pot. un + start => pot. n & pot. un >+ // pot. n & prot. n + def. non null => pot. n & pot. nn >+ // pot. n & prot. n + def. null => pot. n & prot. n >+ // pot. n & prot. n + def. unknown => pot. n & pot. un >+ // pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & prot. n + pot. n & pot. un => pot. n & pot. un >+ // pot. n & prot. n + pot. n & prot. n => pot. n & prot. n >+ // pot. n & prot. n + pot. nn & pot. un => pot. n & pot. nn >+ // pot. n & prot. n + pot. nn & prot. nn => pot. n & pot. nn >+ // pot. n & prot. n + pot. non null => pot. n & pot. nn >+ // pot. n & prot. n + pot. null => pot. n & prot. n >+ // pot. n & prot. n + pot. unknown => pot. n & pot. un >+ // pot. n & prot. n + prot. non null => pot. n & prot. n >+ // pot. n & prot. n + prot. null => pot. n & prot. n >+ // pot. n & prot. n + start => pot. n & prot. n >+ // pot. nn & pot. un + def. non null => pot. nn & pot. un >+ // pot. nn & pot. un + def. null => pot. n & pot. nn >+ // pot. nn & pot. un + def. unknown => pot. nn & pot. un >+ // pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn >+ // pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un >+ // pot. nn & pot. un + pot. nn & prot. nn => pot. nn & pot. un >+ // pot. nn & pot. un + pot. non null => pot. nn & pot. un >+ // pot. nn & pot. un + pot. null => pot. n & pot. nn >+ // pot. nn & pot. un + pot. unknown => pot. nn & pot. un >+ // pot. nn & pot. un + prot. non null => pot. nn & pot. un >+ // pot. nn & pot. un + prot. null => pot. nn & pot. un >+ // pot. nn & pot. un + start => pot. nn & pot. un >+ // pot. nn & prot. nn + def. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + def. null => pot. n & pot. nn >+ // pot. nn & prot. nn + def. unknown => pot. nn & pot. un >+ // pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un // see test1501 >+ // pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. nn & prot. nn + pot. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + pot. null => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. unknown => pot. nn & pot. un >+ // pot. nn & prot. nn + prot. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + prot. null => pot. nn & prot. nn >+ // pot. nn & prot. nn + start => pot. nn & prot. nn >+ // pot. non null + def. non null => pot. non null >+ // pot. non null + def. null => pot. n & pot. nn >+ // pot. non null + def. unknown => pot. nn & pot. un >+ // pot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. non null + pot. n & pot. un => pot. n & pot. nn >+ // pot. non null + pot. n & prot. n => pot. n & pot. nn >+ // pot. non null + pot. nn & pot. un => pot. nn & pot. un >+ // pot. non null + pot. nn & prot. nn => pot. non null >+ // pot. non null + pot. non null => pot. non null >+ // pot. non null + pot. null => pot. n & pot. nn >+ // pot. non null + pot. unknown => pot. nn & pot. un >+ // pot. non null + prot. non null => pot. non null >+ // pot. non null + prot. null => pot. non null >+ // pot. non null + start => pot. non null >+ // pot. null + def. non null => pot. n & pot. nn >+ // pot. null + def. null => pot. null >+ // pot. null + def. unknown => pot. n & pot. un >+ // pot. null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. null + pot. n & pot. un => pot. n & pot. un >+ // pot. null + pot. n & prot. n => pot. null >+ // pot. null + pot. nn & pot. un => pot. n & pot. nn >+ // pot. null + pot. nn & prot. nn => pot. n & pot. nn >+ // pot. null + pot. non null => pot. n & pot. nn >+ // pot. null + pot. null => pot. null >+ // pot. null + pot. unknown => pot. n & pot. un >+ // pot. null + prot. non null => pot. null >+ // pot. null + prot. null => pot. null >+ // pot. null + start => pot. null >+ // pot. unknown + def. non null => pot. nn & pot. un >+ // pot. unknown + def. null => pot. n & pot. un >+ // pot. unknown + def. unknown => pot. unknown >+ // pot. unknown + pot. n & pot. nn => pot. n & pot. nn >+ // pot. unknown + pot. n & pot. un => pot. n & pot. un >+ // pot. unknown + pot. n & prot. n => pot. n & pot. un >+ // pot. unknown + pot. nn & pot. un => pot. nn & pot. un >+ // pot. unknown + pot. nn & prot. nn => pot. nn & pot. un >+ // pot. unknown + pot. non null => pot. nn & pot. un >+ // pot. unknown + pot. null => pot. n & pot. un >+ // pot. unknown + pot. unknown => pot. unknown >+ // pot. unknown + prot. non null => pot. unknown >+ // pot. unknown + prot. null => pot. unknown >+ // pot. unknown + start => pot. unknown >+ // prot. non null + def. non null => pot. nn & prot. nn >+ // prot. non null + def. null => pot. null >+ // prot. non null + def. unknown => pot. unknown >+ // prot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. non null + pot. n & pot. un => pot. n & pot. un >+ // prot. non null + pot. n & prot. n => pot. null >+ // prot. non null + pot. nn & pot. un => pot. nn & pot. un // see test1500 >+ // prot. non null + pot. nn & prot. nn => pot. nn & prot. nn >+ // prot. non null + pot. non null => pot. nn & prot. nn >+ // prot. non null + pot. null => pot. null >+ // prot. non null + pot. unknown => pot. unknown >+ // prot. non null + prot. non null => prot. non null >+ // prot. non null + prot. null => prot. non null >+ // prot. non null + start => prot. non null >+ // prot. null + def. non null => pot. non null >+ // prot. null + def. null => pot. n & prot. n >+ // prot. null + def. unknown => pot. unknown >+ // prot. null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. null + pot. n & pot. un => pot. n & pot. un >+ // prot. null + pot. n & prot. n => pot. n & prot. n >+ // prot. null + pot. nn & pot. un => pot. nn & pot. un >+ // prot. null + pot. nn & prot. nn => pot. non null >+ // prot. null + pot. non null => pot. non null >+ // prot. null + pot. null => pot. n & prot. n >+ // prot. null + pot. unknown => pot. unknown >+ // prot. null + prot. non null => prot. null >+ // prot. null + prot. null => prot. null >+ // prot. null + start => prot. null >+ // start + def. non null => pot. non null >+ // start + def. null => pot. null >+ // start + def. unknown => pot. unknown >+ // start + pot. n & pot. nn => pot. n & pot. nn >+ // start + pot. n & pot. un => pot. n & pot. un >+ // start + pot. n & prot. n => pot. null >+ // start + pot. nn & pot. un => pot. nn & pot. un >+ // start + pot. nn & prot. nn => pot. non null >+ // start + pot. non null => pot. non null >+ // start + pot. null => pot. null >+ // start + pot. unknown => pot. unknown >+ // start + prot. non null => start // PREMATURE may need to be tainted? >+ // start + prot. null => start // PREMATURE may need to be tainted? >+ // start + start => start >+ // addPotentialInitializationsFrom DEFINITION END >+ addPotentialInitializationsFrom = >+ new ThreeDimensionalTransformation("addPotentialInitializationsFrom", >+ new byte[][] { >+ // addPotentialInitializationsFrom INITIALIZER START >+ {0x00,0x00,0x00}, >+ {0x00,0x04,0x04}, >+ {0x00,0x08,0x08}, >+ {0x00,0x0C,0x0C}, >+ {0x00,0x10,0x10}, >+ {0x00,0x14,0x14}, >+ {0x00,0x18,0x18}, >+ {0x00,0x24,0x04}, >+ {0x00,0x28,0x08}, >+ {0x00,0x2C,0x08}, >+ {0x00,0x30,0x10}, >+ {0x00,0x34,0x10}, >+ {0x00,0x38,0x00}, >+ {0x00,0x3C,0x00}, >+ {0x04,0x00,0x04}, >+ {0x04,0x04,0x04}, >+ {0x04,0x08,0x0C}, >+ {0x04,0x0C,0x0C}, >+ {0x04,0x10,0x14}, >+ {0x04,0x14,0x14}, >+ {0x04,0x18,0x18}, >+ {0x04,0x24,0x04}, >+ {0x04,0x28,0x0C}, >+ {0x04,0x2C,0x0C}, >+ {0x04,0x30,0x14}, >+ {0x04,0x34,0x14}, >+ {0x04,0x38,0x04}, >+ {0x04,0x3C,0x04}, >+ {0x08,0x00,0x08}, >+ {0x08,0x04,0x0C}, >+ {0x08,0x08,0x08}, >+ {0x08,0x0C,0x0C}, >+ {0x08,0x10,0x18}, >+ {0x08,0x14,0x18}, >+ {0x08,0x18,0x18}, >+ {0x08,0x24,0x0C}, >+ {0x08,0x28,0x08}, >+ {0x08,0x2C,0x08}, >+ {0x08,0x30,0x18}, >+ {0x08,0x34,0x18}, >+ {0x08,0x38,0x08}, >+ {0x08,0x3C,0x08}, >+ {0x0C,0x00,0x0C}, >+ {0x0C,0x04,0x0C}, >+ {0x0C,0x08,0x0C}, >+ {0x0C,0x0C,0x0C}, >+ {0x0C,0x10,0x18}, >+ {0x0C,0x14,0x18}, >+ {0x0C,0x18,0x18}, >+ {0x0C,0x24,0x0C}, >+ {0x0C,0x28,0x0C}, >+ {0x0C,0x2C,0x0C}, >+ {0x0C,0x30,0x18}, >+ {0x0C,0x34,0x18}, >+ {0x0C,0x38,0x0C}, >+ {0x0C,0x3C,0x0C}, >+ {0x10,0x00,0x10}, >+ {0x10,0x04,0x14}, >+ {0x10,0x08,0x18}, >+ {0x10,0x0C,0x18}, >+ {0x10,0x10,0x10}, >+ {0x10,0x14,0x14}, >+ {0x10,0x18,0x18}, >+ {0x10,0x24,0x14}, >+ {0x10,0x28,0x18}, >+ {0x10,0x2C,0x18}, >+ {0x10,0x30,0x10}, >+ {0x10,0x34,0x10}, >+ {0x10,0x38,0x10}, >+ {0x10,0x3C,0x10}, >+ {0x14,0x00,0x14}, >+ {0x14,0x04,0x14}, >+ {0x14,0x08,0x18}, >+ {0x14,0x0C,0x18}, >+ {0x14,0x10,0x14}, >+ {0x14,0x14,0x14}, >+ {0x14,0x18,0x18}, >+ {0x14,0x24,0x14}, >+ {0x14,0x28,0x18}, >+ {0x14,0x2C,0x18}, >+ {0x14,0x30,0x14}, >+ {0x14,0x34,0x14}, >+ {0x14,0x38,0x14}, >+ {0x14,0x3C,0x14}, >+ {0x18,0x00,0x18}, >+ {0x18,0x04,0x18}, >+ {0x18,0x08,0x18}, >+ {0x18,0x0C,0x18}, >+ {0x18,0x10,0x18}, >+ {0x18,0x14,0x18}, >+ {0x18,0x18,0x18}, >+ {0x18,0x24,0x18}, >+ {0x18,0x28,0x18}, >+ {0x18,0x2C,0x18}, >+ {0x18,0x30,0x18}, >+ {0x18,0x34,0x18}, >+ {0x18,0x38,0x18}, >+ {0x18,0x3C,0x18}, >+ {0x24,0x00,0x24}, >+ {0x24,0x04,0x24}, >+ {0x24,0x08,0x24}, >+ {0x24,0x0C,0x24}, >+ {0x24,0x10,0x14}, >+ {0x24,0x14,0x14}, >+ {0x24,0x18,0x18}, >+ {0x24,0x24,0x24}, >+ {0x24,0x28,0x24}, >+ {0x24,0x2C,0x24}, >+ {0x24,0x30,0x14}, >+ {0x24,0x34,0x14}, >+ {0x24,0x38,0x24}, >+ {0x24,0x3C,0x24}, >+ {0x28,0x00,0x28}, >+ {0x28,0x04,0x24}, >+ {0x28,0x08,0x28}, >+ {0x28,0x0C,0x24}, >+ {0x28,0x10,0x18}, >+ {0x28,0x14,0x18}, >+ {0x28,0x18,0x18}, >+ {0x28,0x24,0x24}, >+ {0x28,0x28,0x28}, >+ {0x28,0x2C,0x28}, >+ {0x28,0x30,0x18}, >+ {0x28,0x34,0x18}, >+ {0x28,0x38,0x28}, >+ {0x28,0x3C,0x28}, >+ {0x2C,0x00,0x2C}, >+ {0x2C,0x04,0x0C}, >+ {0x2C,0x08,0x2C}, >+ {0x2C,0x0C,0x0C}, >+ {0x2C,0x10,0x18}, >+ {0x2C,0x14,0x18}, >+ {0x2C,0x18,0x18}, >+ {0x2C,0x24,0x0C}, >+ {0x2C,0x28,0x2C}, >+ {0x2C,0x2C,0x2C}, >+ {0x2C,0x30,0x18}, >+ {0x2C,0x34,0x18}, >+ {0x2C,0x38,0x2C}, >+ {0x2C,0x3C,0x2C}, >+ {0x30,0x00,0x30}, >+ {0x30,0x04,0x14}, >+ {0x30,0x08,0x18}, >+ {0x30,0x0C,0x18}, >+ {0x30,0x10,0x30}, >+ {0x30,0x14,0x14}, >+ {0x30,0x18,0x18}, >+ {0x30,0x24,0x14}, >+ {0x30,0x28,0x18}, >+ {0x30,0x2C,0x18}, >+ {0x30,0x30,0x30}, >+ {0x30,0x34,0x30}, >+ {0x30,0x38,0x30}, >+ {0x30,0x3C,0x30}, >+ {0x34,0x00,0x34}, >+ {0x34,0x04,0x14}, >+ {0x34,0x08,0x18}, >+ {0x34,0x0C,0x18}, >+ {0x34,0x10,0x34}, >+ {0x34,0x14,0x14}, >+ {0x34,0x18,0x18}, >+ {0x34,0x24,0x14}, >+ {0x34,0x28,0x18}, >+ {0x34,0x2C,0x18}, >+ {0x34,0x30,0x34}, >+ {0x34,0x34,0x34}, >+ {0x34,0x38,0x34}, >+ {0x34,0x3C,0x34}, >+ {0x38,0x00,0x38}, >+ {0x38,0x04,0x04}, >+ {0x38,0x08,0x08}, >+ {0x38,0x0C,0x0C}, >+ {0x38,0x10,0x34}, >+ {0x38,0x14,0x14}, >+ {0x38,0x18,0x18}, >+ {0x38,0x24,0x04}, >+ {0x38,0x28,0x08}, >+ {0x38,0x2C,0x08}, >+ {0x38,0x30,0x34}, >+ {0x38,0x34,0x34}, >+ {0x38,0x38,0x38}, >+ {0x38,0x3C,0x38}, >+ {0x3C,0x00,0x3C}, >+ {0x3C,0x04,0x04}, >+ {0x3C,0x08,0x2C}, >+ {0x3C,0x0C,0x0C}, >+ {0x3C,0x10,0x10}, >+ {0x3C,0x14,0x14}, >+ {0x3C,0x18,0x18}, >+ {0x3C,0x24,0x04}, >+ {0x3C,0x28,0x2C}, >+ {0x3C,0x2C,0x2C}, >+ {0x3C,0x30,0x10}, >+ {0x3C,0x34,0x10}, >+ {0x3C,0x38,0x3C}, >+ {0x3C,0x3C,0x3C}, >+ // addPotentialInitializationsFrom INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input1, >+ UnconditionalFlowInfo input2) { >+ return (UnconditionalFlowInfo) >+ input1.copy().addPotentialInitializationsFrom(input2); >+ } >+ }, >+ mergedWith = >+ // mergedWith DEFINITION START >+ // def. non null + def. non null => def. non null >+ // def. non null + def. null => pot. n & pot. nn >+ // def. null + def. null => def. null >+ // def. unknown + def. non null => def. unknown >+ // def. unknown + def. null => pot. n & pot. un // pot. n priv. over def. unknown >+ // def. unknown + def. unknown => def. unknown >+ // pot. n & pot. nn + def. non null => pot. n & pot. nn >+ // pot. n & pot. nn + def. null => pot. n & pot. nn >+ // pot. n & pot. nn + def. unknown => pot. n & pot. nn >+ // pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. un + def. non null => pot. n & pot. nn >+ // pot. n & pot. un + def. null => pot. n & pot. un >+ // pot. n & pot. un + def. unknown => pot. n & pot. un >+ // pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & pot. un + pot. n & pot. un => pot. n & pot. un >+ // pot. n & prot. n + def. non null => pot. n & pot. nn >+ // pot. n & prot. n + def. null => pot. n & prot. n >+ // pot. n & prot. n + def. unknown => pot. n & pot. un >+ // pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn >+ // pot. n & prot. n + pot. n & pot. un => pot. n & pot. un >+ // pot. n & prot. n + pot. n & prot. n => pot. n & prot. n >+ // pot. nn & pot. un + def. non null => pot. nn & pot. un >+ // pot. nn & pot. un + def. null => pot. n & pot. nn >+ // pot. nn & pot. un + def. unknown => pot. nn & pot. un >+ // pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn >+ // pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un >+ // pot. nn & pot. un + pot. null => pot. n & pot. nn >+ // pot. nn & prot. nn + def. non null => pot. nn & prot. nn >+ // pot. nn & prot. nn + def. null => pot. n & pot. nn >+ // pot. nn & prot. nn + def. unknown => pot. nn & pot. un >+ // pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn >+ // pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un >+ // pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn >+ // pot. nn & prot. nn + pot. null => pot. n & pot. nn >+ // pot. non null + def. non null => pot. non null >+ // pot. non null + def. null => pot. n & pot. nn >+ // pot. non null + def. unknown => pot. nn & pot. un >+ // pot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. non null + pot. n & pot. un => pot. n & pot. nn >+ // pot. non null + pot. n & prot. n => pot. n & pot. nn >+ // pot. non null + pot. nn & pot. un => pot. nn & pot. un >+ // pot. non null + pot. nn & prot. nn => pot. non null >+ // pot. non null + pot. non null => pot. non null >+ // pot. non null + pot. null => pot. n & pot. nn >+ // pot. null + def. non null => pot. n & pot. nn >+ // pot. null + def. null => pot. null >+ // pot. null + def. unknown => pot. n & pot. un >+ // pot. null + pot. n & pot. nn => pot. n & pot. nn >+ // pot. null + pot. n & pot. un => pot. n & pot. un >+ // pot. null + pot. n & prot. n => pot. null >+ // pot. null + pot. null => pot. null >+ // pot. unknown + def. non null => pot. nn & pot. un >+ // pot. unknown + def. null => pot. n & pot. un >+ // pot. unknown + def. unknown => pot. unknown >+ // pot. unknown + pot. n & pot. nn => pot. n & pot. nn >+ // pot. unknown + pot. n & pot. un => pot. n & pot. un >+ // pot. unknown + pot. n & prot. n => pot. n & pot. un >+ // pot. unknown + pot. nn & pot. un => pot. nn & pot. un >+ // pot. unknown + pot. nn & prot. nn => pot. nn & pot. un >+ // pot. unknown + pot. non null => pot. nn & pot. un >+ // pot. unknown + pot. null => pot. n & pot. un >+ // pot. unknown + pot. unknown => pot. unknown >+ // prot. non null + def. non null => pot. nn & prot. nn >+ // prot. non null + def. null => pot. null >+ // prot. non null + def. unknown => def. unknown // test726 >+ // prot. non null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. non null + pot. n & pot. un => pot. n & pot. un >+ // prot. non null + pot. n & prot. n => pot. null >+ // prot. non null + pot. nn & pot. un => pot. nn & pot. un >+ // prot. non null + pot. nn & prot. nn => pot. nn & prot. nn >+ // prot. non null + pot. non null => pot. non null >+ // prot. non null + pot. null => pot. null >+ // prot. non null + pot. unknown => pot. unknown >+ // prot. non null + prot. non null => prot. non null >+ // prot. non null + prot. null => pot. null // PREMATURE use tainted instead >+ // prot. null + def. non null => pot. non null // PREMATURE should become tainted null & pot. nn... not really, depends on the three way merge... or even on the conditions that got there (pb with no contrib prot. null branch) >+ // prot. null + def. null => pot. n & prot. n >+ // prot. null + def. unknown => pot. unknown // PREMATURE possibly wrong, but no test case yet >+ // prot. null + pot. n & pot. nn => pot. n & pot. nn >+ // prot. null + pot. n & pot. un => pot. n & pot. un >+ // prot. null + pot. n & prot. n => pot. n & prot. n >+ // prot. null + pot. nn & pot. un => pot. n & pot. nn >+ // prot. null + pot. nn & prot. nn => pot. n & pot. nn >+ // prot. null + pot. non null => pot. n & pot. nn >+ // prot. null + pot. null => pot. null >+ // prot. null + pot. unknown => pot. unknown // PREMATURE possibly wrong, but no test case yet >+ // prot. null + prot. null => prot. null >+ // start + def. non null => pot. non null >+ // start + def. null => pot. null >+ // start + def. unknown => pot. unknown >+ // start + pot. n & pot. nn => pot. n & pot. nn >+ // start + pot. n & pot. un => pot. n & pot. un >+ // start + pot. n & prot. n => pot. null >+ // start + pot. nn & pot. un => pot. nn & pot. un >+ // start + pot. nn & prot. nn => pot. non null >+ // start + pot. non null => pot. non null >+ // start + pot. null => pot. null >+ // start + pot. unknown => pot. unknown >+ // start + prot. non null => start // PREMATURE should it taint? >+ // start + prot. null => start >+ // start + start => start >+ // mergedWith DEFINITION END >+ new SymmetricalThreeDimensionalTransformation("mergedWith", >+ new byte[][] { >+ // mergedWith INITIALIZER START >+ {0x00,0x00,0x00}, >+ {0x00,0x04,0x04}, >+ {0x00,0x08,0x08}, >+ {0x00,0x0C,0x0C}, >+ {0x00,0x10,0x10}, >+ {0x00,0x14,0x14}, >+ {0x00,0x18,0x18}, >+ {0x00,0x24,0x04}, >+ {0x00,0x28,0x08}, >+ {0x00,0x2C,0x08}, >+ {0x00,0x30,0x10}, >+ {0x00,0x34,0x10}, >+ {0x00,0x38,0x00}, >+ {0x00,0x3C,0x00}, >+ {0x04,0x04,0x04}, >+ {0x04,0x08,0x0C}, >+ {0x04,0x0C,0x0C}, >+ {0x04,0x10,0x14}, >+ {0x04,0x14,0x14}, >+ {0x04,0x18,0x18}, >+ {0x04,0x24,0x04}, >+ {0x04,0x28,0x0C}, >+ {0x04,0x2C,0x0C}, >+ {0x04,0x30,0x14}, >+ {0x04,0x34,0x14}, >+ {0x08,0x08,0x08}, >+ {0x08,0x0C,0x0C}, >+ {0x08,0x10,0x18}, >+ {0x08,0x14,0x18}, >+ {0x08,0x18,0x18}, >+ {0x08,0x24,0x0C}, >+ {0x08,0x28,0x08}, >+ {0x08,0x2C,0x08}, >+ {0x08,0x30,0x18}, >+ {0x08,0x34,0x18}, >+ {0x0C,0x0C,0x0C}, >+ {0x0C,0x10,0x18}, >+ {0x0C,0x14,0x18}, >+ {0x0C,0x18,0x18}, >+ {0x0C,0x24,0x0C}, >+ {0x0C,0x28,0x0C}, >+ {0x0C,0x30,0x18}, >+ {0x0C,0x34,0x18}, >+ {0x10,0x10,0x10}, >+ {0x10,0x14,0x14}, >+ {0x10,0x18,0x18}, >+ {0x10,0x24,0x14}, >+ {0x10,0x28,0x18}, >+ {0x10,0x30,0x10}, >+ {0x10,0x34,0x10}, >+ {0x14,0x14,0x14}, >+ {0x14,0x18,0x18}, >+ {0x14,0x24,0x14}, >+ {0x14,0x28,0x18}, >+ {0x14,0x30,0x14}, >+ {0x18,0x18,0x18}, >+ {0x18,0x24,0x18}, >+ {0x18,0x28,0x18}, >+ {0x18,0x30,0x18}, >+ {0x24,0x24,0x24}, >+ {0x24,0x28,0x24}, >+ {0x24,0x30,0x14}, >+ {0x28,0x28,0x28}, >+ {0x28,0x30,0x18}, >+ {0x2C,0x0C,0x0C}, >+ {0x2C,0x10,0x18}, >+ {0x2C,0x14,0x18}, >+ {0x2C,0x18,0x18}, >+ {0x2C,0x24,0x0C}, >+ {0x2C,0x28,0x2C}, >+ {0x2C,0x2C,0x2C}, >+ {0x2C,0x30,0x18}, >+ {0x2C,0x34,0x18}, >+ {0x30,0x30,0x30}, >+ {0x34,0x14,0x14}, >+ {0x34,0x18,0x18}, >+ {0x34,0x24,0x14}, >+ {0x34,0x28,0x18}, >+ {0x34,0x30,0x34}, >+ {0x34,0x34,0x34}, >+ {0x38,0x04,0x04}, >+ {0x38,0x08,0x18}, >+ {0x38,0x0C,0x18}, >+ {0x38,0x10,0x10}, >+ {0x38,0x14,0x14}, >+ {0x38,0x18,0x18}, >+ {0x38,0x24,0x04}, >+ {0x38,0x28,0x08}, >+ {0x38,0x2C,0x18}, >+ {0x38,0x30,0x34}, >+ {0x38,0x34,0x34}, >+ {0x38,0x38,0x38}, >+ {0x3C,0x04,0x04}, >+ {0x3C,0x08,0x08}, >+ {0x3C,0x0C,0x0C}, >+ {0x3C,0x10,0x10}, >+ {0x3C,0x14,0x14}, >+ {0x3C,0x18,0x18}, >+ {0x3C,0x24,0x24}, >+ {0x3C,0x28,0x2C}, >+ {0x3C,0x2C,0x2C}, >+ {0x3C,0x30,0x10}, >+ {0x3C,0x34,0x10}, >+ {0x3C,0x38,0x10}, >+ {0x3C,0x3C,0x3C}, >+ // mergedWith INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input1, >+ UnconditionalFlowInfo input2) { >+ return input1.copy().mergedWith(input2); >+ } >+ }, >+ newNullInfoRegistry = >+ // newNullInfoRegistry DEFINITION START >+ // start => start >+ // prot. non null => start >+ // prot. null => start >+ // pot. unknown => start >+ // pot. non null => start >+ // pot. nn & prot. nn => start >+ // pot. nn & pot. un => start >+ // pot. null => start >+ // pot. n & prot. n => start >+ // pot. n & pot. un => start >+ // pot. n & pot. nn => start >+ // def. unknown => pot. unknown >+ // def. non null => pot. non null >+ // def. null => pot. null >+ // newNullInfoRegistry DEFINITION END >+ new CreationalTransformation("newNullInfoRegistry", >+ new byte[][] { >+ // newNullInfoRegistry INITIALIZER START >+ {0x00,0x00}, >+ {0x04,0x00}, >+ {0x08,0x00}, >+ {0x0C,0x00}, >+ {0x10,0x00}, >+ {0x14,0x00}, >+ {0x18,0x00}, >+ {0x24,0x04}, >+ {0x28,0x08}, >+ {0x2C,0x00}, >+ {0x30,0x10}, >+ {0x34,0x00}, >+ {0x38,0x00}, >+ {0x3C,0x00}, >+ // newNullInfoRegistry INITIALIZER END >+ }) { >+ UnconditionalFlowInfo output(UnconditionalFlowInfo input) { >+ return NullInfoRegistryTestHarness. >+ testNullInfoRegistry((UnconditionalFlowInfoTestHarness) input); >+ } >+ }; >+ public static final Transformation[] transformations = { >+ markAsComparedEqualToNonNull, >+ markAsComparedEqualToNull, >+ markAsDefinitelyNonNull, >+ markAsDefinitelyNull, >+ markAsDefinitelyUnknown, >+ addInitializationsFrom, >+ addPotentialInitializationsFrom, >+ mergedWith, >+ newNullInfoRegistry >+ }; >+public abstract static class Transformation { >+ public String name; >+ String definitionStartMarker, definitionEndMarker, >+ initializerStartMarker, initializerEndMarker; >+ int dimension; >+ public Map initializedTransitions, computedTransitions; >+ // PREMATURE limit public access >+ int failuresNb; // transient >+// PREMATURE complete the test coverage for NullInfoRegistry (need to consider several classes >+// of transitions so as to avoid considering NullInfoRegistry states and >+// UnconditionalFlowInfo states into the same pool; moreover, cross classes >+// transformations exist. >+Transformation(String name) { >+ this.name = name; >+ this.definitionStartMarker = "// " + name + " " + CodeAnalysis.definitionStartMarker; >+ this.definitionEndMarker = "// " + name + " " + CodeAnalysis.definitionEndMarker; >+ this.initializerStartMarker = "// " + name + " " + CodeAnalysis.initializerStartMarker; >+ this.initializerEndMarker = "// " + name + " " + CodeAnalysis.initializerEndMarker; >+} >+abstract State[] computeOutputs(State[] inputs); >+abstract void hydrate(); >+void fail() { >+ if (this.failuresNb == 0) { >+ System.out.println(this.name + " failures: "); >+ } >+ this.failuresNb++; >+} >+abstract void printTruthTables(File outputDirectory); >+ >+static boolean checkContiguity(String a, String b) { >+ int aLength; >+ if ((aLength = a.length()) != b.length()) { >+ System.out.println("inappropriate string length: " + a + " vs " + b); >+ return false; >+ } >+ int status = 0; >+ for (int i = 0; i < aLength; i++) { >+ if (a.charAt(i) != b.charAt(i)) { >+ status++; >+ } >+ } >+ if (status != 1) { >+ System.out.println("non contiguous strings: " + a + " vs " + b); >+ return false; >+ } >+ return true; >+} >+ >+final static String truthTableRowNames[] = { // need a specific order to yield simplication opportunities >+ "000000", >+ "000100", >+ "001100", >+ "001000", >+ "011000", >+ "011100", >+ "010100", >+ "010000", >+ "110000", >+ "110100", >+ "111100", >+ "111000", >+ "101000", >+ "101100", >+ "100100", >+ "100000", >+ // PREMATURE cheated to group first four bits... reconsider >+ "000001", >+ "000011", >+ "000010", >+ "000110", >+ "000111", >+ "000101", >+ "001101", >+ "001111", >+ "001110", >+ "001010", >+ "001011", >+ "001001", >+ "011001", >+ "011011", >+ "011010", >+ "011110", >+ "011111", >+ "011101", >+ "010101", >+ "010111", >+ "010110", >+ "010010", >+ "010011", >+ "010001", >+ "110001", >+ "110011", >+ "110010", >+ "110110", >+ "110111", >+ "110101", >+ "111101", >+ "111111", >+ "111110", >+ "111010", >+ "111011", >+ "111001", >+ "101001", >+ "101011", >+ "101010", >+ "101110", >+ "101111", >+ "101101", >+ "100101", >+ "100111", >+ "100110", >+ "100010", >+ "100011", >+ "100001", >+ }; >+ >+private static Map ranksForStates; >+int rankForState(State state) { >+ int length; >+ if (ranksForStates == null) { >+ ranksForStates = new HashMap(length = truthTableRowNames.length); >+ for (int i = 0; i < length; i++) { >+ ranksForStates.put(truthTableRowNames[i], new Integer(i)); >+ } >+ } >+ Integer rank; >+ if ((rank = (Integer) ranksForStates.get(state.printableBitsField)) != null) { >+ return rank.intValue(); >+ } >+ return 0; >+} >+ >+abstract void reinitializeFromComments(BufferedReader input, BufferedWriter output); >+abstract void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output, >+ State[] consideredStates); >+/** >+ * Run a test against UnconditionalFlowInfo by comparing the transitions as memorized >+ * into the initializer and as delivered by UnconditionalFlowInfo for various positions >+ * in the encoding and return the number of failures. >+ * @return the number of failures, that is 0 if the results match the expectations >+ */ >+abstract int test(); >+} >+abstract static class TwoDimensionalTransformation extends Transformation { >+TwoDimensionalTransformation(String name, byte[][] transitions) { >+ super(name); >+ this.dimension = 2; >+ int length; >+ this.initializedTransitions = new HashMap(length = transitions.length); >+ State input1; >+ for (int i = 0; i < length; i++) { >+ if (transitions[i].length != 2) { >+ throw new IllegalArgumentException("transitions should have two entries"); >+ } >+ input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken >+ if (this.initializedTransitions.get(input1) != null) { >+ throw new IllegalArgumentException("duplicate entry"); >+ } >+ this.initializedTransitions.put(input1, State.states[transitions[i][1]]); >+ } >+} >+State[] computeOutputs(State[] inputs) { >+ Map resultAccumulator = new HashMap(State.stateMaxValue + 1); >+ hydrate(); // pre-compute all possible combinations, then cache them >+ for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { >+ resultAccumulator.put(this.computedTransitions.get(inputs[i]), null); >+ } >+ int length; >+ State[] result = new State[length = resultAccumulator.size()]; >+ Iterator resultIterator = resultAccumulator.keySet().iterator(); >+ for (int j = 0; j < length; j++) { >+ result[j] = (State) resultIterator.next(); >+ } >+ return result; >+} >+void hydrate() { >+ if (this.computedTransitions == null) { >+ State input, output; >+ this.computedTransitions = new HashMap(State.stateMaxValue + 1); >+ for (int i = 0, length = State.states.length; i < length; i++) { >+ output = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input = State.states[i]), >+ TestLocalVariableBinding.local0)).asState(); >+ if (input.symbolic && !output.symbolic) { >+ System.err.println(this.name + " generates non-symbolic state " + >+ output + " upon entry: " + input); >+ } >+ this.computedTransitions.put(input, output); >+ } >+ } >+} >+abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input, TestLocalVariableBinding local); >+ >+void printTruthTables(File outputDirectory) { >+ try { >+ String outputFileName = outputDirectory.getPath() + File.separator + this.name + ".txt"; >+ PrintWriter out = new PrintWriter(new FileOutputStream( >+ new File(outputFileName))); >+ System.out.println("Printing " + outputFileName); >+ out.println("======================================================"); >+ out.println("Truth table for " + this.name ); >+ char truthValues[][] = new char[State.statesNb][State.stateWidth]; >+ int row, column; >+ for (row = 0; row < State.statesNb; row++) { >+ for (column = 0; column < State.stateWidth; column++) { >+ truthValues[row][column] = '.'; >+ } >+ } >+ boolean keepRow[] = new boolean[State.statesNb]; >+ Iterator i1 = this.initializedTransitions.entrySet().iterator(); >+ while (i1.hasNext()) { >+ Map.Entry transitionsSet = (Map.Entry) i1.next(); >+ State input = (State) transitionsSet.getKey(); >+ keepRow[row = rankForState(input)] = true; >+ for (int bit = 0; bit < State.stateWidth; bit++) { >+ truthValues[row][bit] = >+ ((State) transitionsSet.getValue()).printableBitsField.charAt(bit); >+ } >+ } >+ StringBuffer line; >+ line = new StringBuffer(140); >+ line.append(" "); >+ for (int i = 1; i <= State.stateWidth; i++) { >+ line.append(i); >+ line.append(' '); >+ } >+ out.println(line); >+ line = new StringBuffer(140); >+ line.append(" ---------------------"); >+ out.println(line); >+ for (row = 0; row < State.statesNb; row++) { >+ if (keepRow[row]) { >+ line = new StringBuffer(140); >+ line.append(truthTableRowNames[row]); >+ line.append(" | "); >+ for (int i = 0; i < State.stateWidth; i++) { >+ line.append(truthValues[row][i]); >+ line.append(' '); >+ } >+ out.println(line); >+ } >+ } >+ out.println("======================================================"); >+ out.flush(); >+ out.close(); >+ } >+ catch (Throwable t) { >+ // PREMATURE improve error handling >+ } >+} >+ >+void reinitializeFromComments(BufferedReader input, BufferedWriter output) { >+ String line, tab = ""; >+ int cursor; >+ char c; >+ this.initializedTransitions = new HashMap(State.stateMaxValue); >+ int lineNumber = 0; >+ try { >+ while ((line = input.readLine()) != null) { >+ lineNumber++; >+ output.write(line); >+ output.write('\n'); >+ if ((cursor = line.indexOf(definitionStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(definitionEndMarker) == -1) { >+ lineNumber++; >+ final int >+ start = 0, >+ commentStart = 1, >+ commentFound = 2, >+ firstState = 10, >+ firstStateWS = 11, >+ implies = 20, >+ impliesWS = 21, >+ secondState = 30, >+ secondStateWS = 31, // caveat, multi-state >+ error = 99; >+ int state = start, >+ firstStateStart = 0, firstStateEnd = 0, firstStateWhiteSpace = 0, >+ secondStateStart = 0, secondStateEnd = 0, secondStateWhiteSpace = 0; >+ char current; >+ analysis: for (int i = 0, length = line.length(); i < length; i++) { >+ current = line.charAt(i); >+ switch (state) { >+ case start: >+ if (current == '/') { >+ state = commentStart; >+ } else if (! Character.isWhitespace(current)) { >+ state = error; >+ break analysis; >+ } >+ break; >+ case commentStart: >+ if (current == '/') { >+ state = commentFound; >+ } else { >+ state = error; >+ break analysis; >+ } >+ break; >+ case commentFound: >+ if (! Character.isWhitespace(current)) { >+ firstStateStart = firstStateEnd = i; >+ state = firstState; >+ } >+ break; >+ case firstState: >+ if (Character.isWhitespace(current)) { >+ state = firstStateWS; >+ firstStateWhiteSpace = 1; >+ } else { >+ firstStateEnd++; >+ } >+ break; >+ case firstStateWS: >+ if (current == '=') { >+ state = implies; >+ } else if (Character.isWhitespace(current)) { >+ firstStateWhiteSpace++; >+ } else { >+ state = firstState; >+ firstStateEnd += firstStateWhiteSpace + 1; >+ } >+ break; >+ case implies: >+ if (current == '>') { >+ state = impliesWS; >+ } else { >+ state = error; >+ break analysis; >+ } >+ break; >+ case impliesWS: >+ if (! Character.isWhitespace(current)) { >+ secondStateStart = secondStateEnd = i; >+ state = secondState; >+ } >+ break; >+ case secondState: >+ if (current == '/') { >+ break analysis; >+ } else if (Character.isWhitespace(current)) { >+ state = secondStateWS; >+ secondStateWhiteSpace = 1; >+ } else { >+ secondStateEnd++; >+ } >+ break; >+ case secondStateWS: >+ if (current == '/') { >+ state = secondState; >+ break analysis; >+ } else if (current == 'C') { >+ state++; >+ } else if (Character.isWhitespace(current)) { >+ secondStateWhiteSpace++; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 1; >+ } >+ break; >+ case secondStateWS + 1: >+ if (current == '/') { >+ state = secondState; >+ break analysis; >+ } else if (current == 'H') { >+ state++; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 2; >+ } >+ break; >+ case secondStateWS + 2: >+ if (current == '/') { >+ state = secondState; >+ break analysis; >+ } else if (current == 'E') { >+ state++; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 3; >+ } >+ break; >+ case secondStateWS + 3: >+ if (current == '/') { >+ state = secondState; >+ break analysis; >+ } else if (current == 'C') { >+ state++; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 4; >+ } >+ break; >+ case secondStateWS + 4: >+ if (current == '/' || current == 'K') { >+ state = secondState; >+ break analysis; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 5; >+ } >+ break; >+ >+ } >+ } >+ if (state == error || state < secondState) { >+ System.err.println("Could not interpret comment definition"); // PREMATURE improve diagnostic >+ } else { >+ if (state > secondStateWS) { >+ secondStateEnd += (state - secondState); >+ } >+ String stateName; >+ State first, second; >+ if ((first = State.fromSymbolicName( >+ stateName = line.substring(firstStateStart, firstStateEnd + 1))) >+ == null) { >+ System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic >+ } >+ if ((second = State.fromSymbolicName( >+ stateName = line.substring(secondStateStart, secondStateEnd + 1))) >+ == null) { >+ System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic >+ } >+ if (first != null && second != null) { >+ if (this.initializedTransitions.get(first) != null) { >+ System.err.println("Line " + lineNumber + ": Skipping duplicate entry for state: " + first); // PREMATURE improve diagnostic >+ } else { >+ this.initializedTransitions.put(first, second); >+ } >+ } >+ } >+ output.write(line); >+ output.write('\n'); >+ } >+ Iterator firsts = State.symbolicStates(); >+ State first; >+ while (firsts.hasNext()) { >+ first = (State) firsts.next(); >+ if (this.initializedTransitions.get(first) == null) { >+ System.err.println("Adding missing transition for state: " + first); >+ output.write(tab); >+ output.write("// "); >+ output.write(first.toString()); >+ output.write(" => start\t\t CHECK\n"); >+ } >+ } >+ } >+ output.write(tab + definitionEndMarker + "\n"); >+ } >+ if (line != null && (cursor = line.indexOf(initializerStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ tab = ""; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(initializerEndMarker) == -1) { >+ // loop >+ } >+ SortedMap sorted = new TreeMap(this.initializedTransitions); >+ Iterator transitions = sorted.entrySet().iterator(); >+ Map.Entry transition; >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ output.write(tab); >+ output.write('{'); >+ output.write(((State)transition.getKey()).hexString); >+ output.write(','); >+ output.write(((State)transition.getValue()).hexString); >+ output.write("},"); >+ output.write('\n'); >+ } >+ output.write(tab + initializerEndMarker + "\n"); >+ } >+ } >+ } >+ output.flush(); >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+} >+ >+void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output, >+ State[] consideredStates) { >+ String line, tab = ""; >+ int cursor; >+ char c; >+ State result; >+ try { >+ while ((line = input.readLine()) != null) { >+ output.write(line); >+ output.write('\n'); >+ if ((cursor = line.indexOf(definitionStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(definitionEndMarker) == -1) { >+ // loop >+ } >+ int i, length; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ output.write(tab); >+ output.write("// "); >+ output.write(consideredStates[i].name); >+ output.write(" => "); >+ output.write( >+ (result = (State) this.computedTransitions.get(consideredStates[i])).name); >+ if (!result.symbolic || >+ result != this.initializedTransitions.get(consideredStates[i])) { >+ output.write("\t\t CHECK"); >+ } >+ output.write('\n'); >+ } >+ output.write(tab + definitionEndMarker + "\n"); >+ } >+ } >+ if (line != null && (cursor = line.indexOf(initializerStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ tab = ""; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(initializerEndMarker) == -1) { >+ // loop >+ } >+ int i, length; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ output.write(tab); >+ output.write('{'); >+ output.write(consideredStates[i].hexString); >+ output.write(','); >+ output.write( >+ ((State) this.computedTransitions.get(consideredStates[i])).hexString); >+ output.write("},"); >+ output.write('\n'); >+ } >+ output.write(tab + initializerEndMarker + "\n"); >+ } >+ } >+ } >+ output.flush(); >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+} >+int test() { >+ Iterator transitions = this.initializedTransitions.entrySet().iterator(); >+ State input, expectedOutput, effectiveOutput; >+ Map.Entry transition; >+ this.failuresNb = 0; // reset >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ input = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input), >+ TestLocalVariableBinding.local0)).asState(); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ transitions = this.initializedTransitions.entrySet().iterator(); >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ input = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input, 64), >+ TestLocalVariableBinding.local64)).asState(64); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64) instead of: " + expectedOutput.printableBitsField); >+ } >+ if (input == State.start) { >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(expectedOutput), >+ TestLocalVariableBinding.local64)).asState(64); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 64) instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ transitions = this.initializedTransitions.entrySet().iterator(); >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ input = (State) transition.getKey(); >+ if (input == State.start) { >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(expectedOutput, 64), >+ TestLocalVariableBinding.local128)).asState(128); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 128) instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ return this.failuresNb; >+} >+} >+abstract static class CreationalTransformation extends TwoDimensionalTransformation { >+CreationalTransformation(String name, byte[][] transitions) { >+ super(name, transitions); >+} >+void hydrate() { >+ if (this.computedTransitions == null) { >+ State input, output; >+ this.computedTransitions = new HashMap(State.stateMaxValue + 1); >+ for (int i = 0, length = State.states.length; i < length; i++) { >+ output = ((NullInfoRegistryTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input = State.states[i]), >+ TestLocalVariableBinding.local0)).asState(); >+ if (input.symbolic && !output.symbolic) { >+ System.err.println(this.name + " generates non-symbolic state " + >+ output + " upon entry: " + input); >+ } >+ this.computedTransitions.put(input, output); >+ } >+ } >+} >+UnconditionalFlowInfo output(UnconditionalFlowInfo input, TestLocalVariableBinding local) { >+ return output(input); >+} >+abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input); >+int test() { >+ Iterator transitions = this.initializedTransitions.entrySet().iterator(); >+ State input, expectedOutput, effectiveOutput; >+ Map.Entry transition; >+ this.failuresNb = 0; // reset >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ input = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((NullInfoRegistryTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input), >+ TestLocalVariableBinding.local0)).asState(); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ transitions = this.initializedTransitions.entrySet().iterator(); >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ input = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((NullInfoRegistryTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input, 64))).asState(64); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64) instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ return this.failuresNb; >+} >+} >+public abstract static class ThreeDimensionalTransformation extends Transformation { >+ThreeDimensionalTransformation(String name) { >+ super(name); >+ this.dimension = 3; >+} >+ThreeDimensionalTransformation(String name, byte[][] transitions) { >+ super(name); >+ this.dimension = 3; >+ int length; >+ this.initializedTransitions = new HashMap(length = transitions.length); >+ State input1, input2; >+ for (int i = 0; i < length; i++) { >+ if (transitions[i].length != 3) { >+ throw new IllegalArgumentException("transitions should have three entries"); >+ } >+ input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken >+ input2 = State.states[transitions[i][1]]; >+ Map transitionsForInput1 = (Map) this.initializedTransitions.get(input1); >+ if (transitionsForInput1 == null) { >+ transitionsForInput1 = new HashMap(length); >+ this.initializedTransitions.put(input1, transitionsForInput1); >+ } >+ if (transitionsForInput1.get(input2) != null) { >+ throw new IllegalArgumentException("duplicate entry"); >+ } >+ transitionsForInput1.put(input2, State.states[transitions[i][2]]); >+ } >+} >+State[] computeOutputs(State[] inputs) { >+ Map resultAccumulator = new HashMap(State.stateMaxValue + 1); >+ hydrate(); // pre-compute all possible combinations, then cache them >+ for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { >+ for (int i2 = 0; i2 < inputsLength; i2++) { >+ resultAccumulator.put( >+ ((Map) this.computedTransitions.get(inputs[i])).get(inputs[i2]), null); >+ } >+ } >+ int length; >+ State[] result = new State[length = resultAccumulator.size()]; >+ Iterator resultIterator = resultAccumulator.keySet().iterator(); >+ for (int j = 0; j < length; j++) { >+ result[j] = (State) resultIterator.next(); >+ } >+ return result; >+} >+void hydrate() { >+ if (this.computedTransitions == null) { >+ State input1, input2, output; >+ this.computedTransitions = new HashMap(State.stateMaxValue + 1); >+ Map entry; >+ for (int i = 0, length = State.states.length; i < length; i++) { >+ entry = new HashMap(State.stateMaxValue + 1); >+ this.computedTransitions.put(input1 = State.states[i], entry); >+ for (int j = 0; j < length; j++) { >+ output = ((UnconditionalFlowInfoTestHarness) >+ output(UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input1), >+ UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2 = State.states[j]))).asState(); >+ if (input1.symbolic && input2.symbolic && !output.symbolic) { >+ System.err.println(this.name + " generates non-symbolic state " + >+ output + " upon entry: " + input1 + " + " + input2); >+ } >+ entry.put(input2, output); >+ } >+ } >+ } >+} >+abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input1, UnconditionalFlowInfo input2); >+void printDefinitions(BufferedWriter output, State[] consideredStates, String tab) >+ throws IOException { >+ int i, j, length; >+ State result; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ for (j = 0; j < length; j++) { >+ output.write(tab); >+ output.write("// "); >+ output.write(consideredStates[i].name); >+ output.write(" + "); >+ output.write(consideredStates[j].name); >+ output.write(" => "); >+ output.write( >+ (result = (State) >+ ((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name); >+ if (!result.symbolic || >+ result != this.initializedTransitions.get(consideredStates[i])) { >+ output.write("\t\t CHECK"); >+ } >+ output.write('\n'); >+ } >+ } >+} >+void printInitializers(BufferedWriter output, State[] consideredStates, String tab) >+ throws IOException { >+ int i, j, length; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ for (j = 0; j < length; j++) { >+ output.write(tab); >+ output.write('{'); >+ output.write(consideredStates[i].hexString); >+ output.write(','); >+ output.write(consideredStates[j].hexString); >+ output.write(','); >+ output.write( >+ ((State) >+ ((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).hexString); >+ output.write("},"); >+ output.write('\n'); >+ } >+ } >+} >+void printMissingEntries(BufferedWriter output, String tab) throws IOException { >+ Iterator firsts = State.symbolicStates(), seconds; >+ State first, second; >+ Map transitions; >+ while (firsts.hasNext()) { >+ first = (State) firsts.next(); >+ seconds = State.symbolicStates(); >+ if ((transitions = (Map) this.initializedTransitions.get(first)) >+ == null) { >+ while (seconds.hasNext()) { >+ second = (State) seconds.next(); >+ System.err.println("Adding missing transition for states (" + first + ", " + second + ")"); >+ output.write(tab); >+ output.write("// "); >+ output.write(first.toString()); >+ output.write(" + "); >+ output.write(second.toString()); >+ output.write(" => start\t\t CHECK\n"); >+ } >+ } else { >+ while (seconds.hasNext()) { >+ second = (State) seconds.next(); >+ if (transitions.get(second) == null) { >+ System.err.println("Adding missing transition for states (" + first + ", " + second + ")"); >+ output.write(tab); >+ output.write("// "); >+ output.write(first.toString()); >+ output.write(" + "); >+ output.write(second.toString()); >+ output.write(" => start\t\t CHECK\n"); >+ } >+ } >+ } >+ } >+} >+void printTruthTables(File outputDirectory) { >+ for (int bit = 1; bit <= State.stateWidth; bit++) { >+ try { >+ String outputFileName = outputDirectory.getPath() + File.separator + this.name + "_" + bit + ".txt"; >+ PrintWriter out = new PrintWriter(new FileOutputStream( >+ new File(outputFileName))); >+ System.out.println("Printing " + outputFileName); >+ out.println("======================================================"); >+ out.println("Truth table for " + this.name + " null bit " + bit); >+ char truthValues[][] = new char[State.statesNb][State.statesNb]; >+ int row, column; >+ for (row = 0; row < State.statesNb; row++) { >+ for (column = 0; column < State.statesNb; column++) { >+ truthValues[row][column] = '.'; >+ } >+ } >+ if (false) { // checking row names >+ boolean gotProblem = false; >+ if (truthTableRowNames.length > State.statesNb) { >+ System.out.println("row names table contains too many rows"); >+ gotProblem = true; >+ } >+ else if (truthTableRowNames.length < State.statesNb) { >+ System.out.println("row names table contains too few rows"); >+ gotProblem = true; >+ } >+ Map check = new HashMap(State.statesNb); >+ for (row = 0; row < truthTableRowNames.length; row++) { >+ if (check.containsKey(truthTableRowNames[row])) { >+ System.out.println("duplicate row: " + truthTableRowNames[row]); >+ gotProblem = true; >+ } >+ else { >+ check.put(truthTableRowNames[row], null); >+ } >+ if (row > 0 && !checkContiguity(truthTableRowNames[row - 1], truthTableRowNames[row])) { >+ gotProblem = true; >+ } >+ } >+ // assertFalse("invalid rows table", gotProblem); >+ } >+ boolean keepRow[] = new boolean[State.statesNb], >+ keepColumn[] = new boolean[State.statesNb]; >+ Iterator i1 = this.initializedTransitions.entrySet().iterator(); >+ while (i1.hasNext()) { >+ Map.Entry transitionsSet = (Map.Entry) i1.next(); >+ State first = (State) transitionsSet.getKey(); >+ Iterator i2 = ((Map) transitionsSet.getValue()).entrySet().iterator(); >+ while (i2.hasNext()) { >+ Map.Entry transition = (Map.Entry) i2.next(); >+ mark(truthValues, keepRow, keepColumn, rankForState(first), >+ rankForState((State) transition.getKey()), >+ ((State) transition.getValue()).printableBitsField.charAt(bit - 1)); >+ } >+ } >+ for (row = 0; row < State.statesNb; row += 2) { >+ if (keepRow[row]) { >+ keepRow[row + 1] = true; >+ } >+ else if (keepRow[row + 1]) { >+ keepRow[row] = true; >+ } >+ if (keepColumn[row]) { >+ keepColumn[row + 1] = true; >+ } >+ else if (keepColumn[row + 1]) { >+ keepColumn[row] = true; >+ } >+ } >+ StringBuffer line; >+ for (int i = 0; i < State.stateWidth; i++) { >+ line = new StringBuffer(140); >+ line.append(" "); >+ for (column = 0; column < State.statesNb; column++) { >+ if (keepColumn[column]) { >+ line.append(truthTableRowNames[column].charAt(i)); >+ line.append(' '); >+ } >+ } >+ out.println(line); >+ } >+ line = new StringBuffer(140); >+ line.append(" --"); >+ for (column = 0; column < State.statesNb; column++) { >+ if (keepColumn[column]) { >+ line.append('-'); >+ line.append('-'); >+ } >+ } >+ out.println(line); >+ for (row = 0; row < State.statesNb; row++) { >+ if (keepRow[row]) { >+ line = new StringBuffer(140); >+ line.append(truthTableRowNames[row]); >+ line.append(" | "); >+ for (column = 0; column < State.statesNb; column++) { >+ if (keepColumn[column]) { >+ line.append(truthValues[row][column]); >+ line.append(' '); >+ } >+ } >+ out.println(line); >+ } >+ } >+ out.println("======================================================"); >+ out.flush(); >+ out.close(); >+ } >+ catch (Throwable t) { >+ // PREMATURE improve error handling >+ } >+ } >+} >+ >+void mark(char truthValues[][], boolean keepRow[], boolean keepColumn[], >+ int row, int column, char value) { >+ truthValues[row][column] = value; >+ keepRow[row] = true; >+ keepColumn[column] = true; >+} >+ >+void reinitializeFromComments(BufferedReader input, BufferedWriter output) { >+ String line, tab = ""; >+ int cursor; >+ char c; >+ this.initializedTransitions = new HashMap(State.stateMaxValue); >+ int lineNumber = 0; >+ try { >+ while ((line = input.readLine()) != null) { >+ lineNumber++; >+ output.write(line); >+ output.write('\n'); >+ if ((cursor = line.indexOf(definitionStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(definitionEndMarker) == -1) { >+ lineNumber++; >+ final int >+ start = 0, >+ commentStart = 1, >+ commentFound = 2, >+ firstState = 10, >+ firstStateWS = 11, >+ plus = 20, >+ secondState = 30, >+ secondStateWS = 31, >+ implies = 40, >+ impliesWS = 41, >+ thirdState = 50, >+ thirdStateWS = 51, // caveat, multi-state >+ error = 99; >+ int state = start, >+ firstStateStart = 0, firstStateEnd = 0, firstStateWhiteSpace = 0, >+ secondStateStart = 0, secondStateEnd = 0, secondStateWhiteSpace = 0, >+ thirdStateStart = 0, thirdStateEnd = 0, thirdStateWhiteSpace = 0; >+ char current; >+ analysis: for (int i = 0, length = line.length(); i < length; i++) { >+ current = line.charAt(i); >+ switch (state) { >+ case start: >+ if (current == '/') { >+ state = commentStart; >+ } else if (! Character.isWhitespace(current)) { >+ state = error; >+ break analysis; >+ } >+ break; >+ case commentStart: >+ if (current == '/') { >+ state = commentFound; >+ } else { >+ state = error; >+ break analysis; >+ } >+ break; >+ case commentFound: >+ if (! Character.isWhitespace(current)) { >+ firstStateStart = firstStateEnd = i; >+ state = firstState; >+ } >+ break; >+ case firstState: >+ if (Character.isWhitespace(current)) { >+ state = firstStateWS; >+ firstStateWhiteSpace = 1; >+ } else { >+ firstStateEnd++; >+ } >+ break; >+ case firstStateWS: >+ if (current == '+') { >+ state = plus; >+ } else if (Character.isWhitespace(current)) { >+ firstStateWhiteSpace++; >+ } else { >+ state = firstState; >+ firstStateEnd += firstStateWhiteSpace + 1; >+ } >+ break; >+ case plus: >+ if (! Character.isWhitespace(current)) { >+ secondStateStart = secondStateEnd = i; >+ state = secondState; >+ } >+ break; >+ case secondState: >+ if (Character.isWhitespace(current)) { >+ state = secondStateWS; >+ secondStateWhiteSpace = 1; >+ } else { >+ secondStateEnd++; >+ } >+ break; >+ case secondStateWS: >+ if (current == '=') { >+ state = implies; >+ } else if (Character.isWhitespace(current)) { >+ secondStateWhiteSpace++; >+ } else { >+ state = secondState; >+ secondStateEnd += secondStateWhiteSpace + 1; >+ } >+ break; >+ case implies: >+ if (current == '>') { >+ state = impliesWS; >+ } else { >+ state = error; >+ break analysis; >+ } >+ break; >+ case impliesWS: >+ if (! Character.isWhitespace(current)) { >+ thirdStateStart = thirdStateEnd = i; >+ state = thirdState; >+ } >+ break; >+ case thirdState: >+ if (current == '/') { >+ break analysis; >+ } else if (Character.isWhitespace(current)) { >+ state = thirdStateWS; >+ thirdStateWhiteSpace = 1; >+ } else { >+ thirdStateEnd++; >+ } >+ break; >+ case thirdStateWS: >+ if (current == '/') { >+ state = thirdState; >+ break analysis; >+ } else if (current == 'C') { >+ state++; >+ } else if (Character.isWhitespace(current)) { >+ thirdStateWhiteSpace++; >+ } else { >+ state = thirdState; >+ thirdStateEnd += thirdStateWhiteSpace + 1; >+ } >+ break; >+ case thirdStateWS + 1: >+ if (current == '/') { >+ state = thirdState; >+ break analysis; >+ } else if (current == 'H') { >+ state++; >+ } else { >+ state = thirdState; >+ thirdStateEnd += thirdStateWhiteSpace + 2; >+ } >+ break; >+ case thirdStateWS + 2: >+ if (current == '/') { >+ state = thirdState; >+ break analysis; >+ } else if (current == 'E') { >+ state++; >+ } else { >+ state = thirdState; >+ thirdStateEnd += thirdStateWhiteSpace + 3; >+ } >+ break; >+ case thirdStateWS + 3: >+ if (current == '/') { >+ state = thirdState; >+ break analysis; >+ } else if (current == 'C') { >+ state++; >+ } else { >+ state = thirdState; >+ thirdStateEnd += thirdStateWhiteSpace + 4; >+ } >+ break; >+ case thirdStateWS + 4: >+ if (current == '/' || current == 'K') { >+ state = thirdState; >+ break analysis; >+ } else { >+ state = thirdState; >+ thirdStateEnd += thirdStateWhiteSpace + 5; >+ } >+ break; >+ >+ } >+ } >+ if (state == error || state < thirdState) { >+ System.err.println("Could not interpret comment definition"); // PREMATURE improve diagnostic >+ } else { >+ if (state > thirdStateWS) { >+ thirdStateEnd += (state - thirdState); >+ } >+ String stateName; >+ State first, second, third; >+ if ((first = State.fromSymbolicName( >+ stateName = line.substring(firstStateStart, firstStateEnd + 1))) >+ == null) { >+ System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic >+ } >+ if ((second = State.fromSymbolicName( >+ stateName = line.substring(secondStateStart, secondStateEnd + 1))) >+ == null) { >+ System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic >+ } >+ if ((third = State.fromSymbolicName( >+ stateName = line.substring(thirdStateStart, thirdStateEnd + 1))) >+ == null) { >+ System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic >+ } >+ if (first != null && second != null && third != null) { >+ Map transitions; >+ if ((transitions = (Map) this.initializedTransitions.get(first)) == null) { >+ transitions = new HashMap(State.stateMaxValue + 1); >+ this.initializedTransitions.put(first, transitions); >+ } >+ if (transitions.get(second) != null) { >+ System.err.println("Line " + lineNumber + ": Skipping duplicate entry for states: (" + first >+ + ", " + second + ")"); // PREMATURE improve diagnostic >+ } else { >+ transitions.put(second, third); >+ } >+ } >+ } >+ output.write(line); >+ output.write('\n'); >+ } >+ } >+ printMissingEntries(output, tab); >+ output.write(tab + definitionEndMarker + "\n"); >+ } >+ if (line != null && (cursor = line.indexOf(initializerStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ tab = ""; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(initializerEndMarker) == -1) { >+ // loop >+ } >+ SortedMap sortedTransitionsSet = new TreeMap(this.initializedTransitions); >+ Iterator transitionsSets = sortedTransitionsSet.entrySet().iterator(); >+ Map.Entry transitionsSet; >+ while (transitionsSets.hasNext()) { >+ transitionsSet = (Map.Entry) transitionsSets.next(); >+ SortedMap sortedTransitions = new TreeMap((Map) transitionsSet.getValue()); >+ Iterator transitions = sortedTransitions.entrySet().iterator(); >+ Map.Entry transition; >+ while (transitions.hasNext()) { >+ transition = (Map.Entry) transitions.next(); >+ output.write(tab); >+ output.write('{'); >+ output.write(((State)transitionsSet.getKey()).hexString); >+ output.write(','); >+ output.write(((State)transition.getKey()).hexString); >+ output.write(','); >+ output.write(((State)transition.getValue()).hexString); >+ output.write("},"); >+ output.write('\n'); >+ } >+ } >+ output.write(tab + initializerEndMarker + "\n"); >+ } >+ } >+ } >+ output.flush(); >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+} >+void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output, >+ State[] consideredStates) { >+ String line, tab = ""; >+ int cursor; >+ char c; >+ try { >+ while ((line = input.readLine()) != null) { >+ output.write(line); >+ output.write('\n'); >+ if ((cursor = line.indexOf(definitionStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(definitionEndMarker) == -1) { >+ // loop >+ } >+ printDefinitions(output, consideredStates, tab); >+ output.write(tab + definitionEndMarker + "\n"); >+ } >+ } >+ if (line != null && (cursor = line.indexOf(initializerStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ tab = ""; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(initializerEndMarker) == -1) { >+ // loop >+ } >+ printInitializers(output, consideredStates, tab); >+ output.write(tab + initializerEndMarker + "\n"); >+ } >+ } >+ } >+ output.flush(); >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+} >+int test() { >+ return test(1, false); >+} >+int test(int combinationTestsLoopsNb, boolean skipHighOrderBits) { >+ Iterator transitionsSetsIterator, transitionsIterator; >+ State input1, input2, expectedOutput, effectiveOutput; >+ Map.Entry transition, transitionsSet; >+ this.failuresNb = 0; // reset >+ this.failuresNb = 0; // reset >+ long start = 0; >+ if (combinationTestsLoopsNb > 1) { >+ start = System.currentTimeMillis(); >+ } >+ for (int l = 0; l < combinationTestsLoopsNb ; l++) { >+ transitionsSetsIterator = this.initializedTransitions.entrySet().iterator(); >+ while (transitionsSetsIterator.hasNext()) { >+ transitionsSet = (Map.Entry) transitionsSetsIterator.next(); >+ input1 = (State) transitionsSet.getKey(); >+ transitionsIterator = ((Map) transitionsSet.getValue()). >+ entrySet().iterator(); >+ while (transitionsIterator.hasNext()) { >+ transition = (Map.Entry) transitionsIterator.next(); >+ input2 = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) output( >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1), >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2))) >+ .asState(); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ } >+ if (combinationTestsLoopsNb > 1) { >+ System.out.println(this.name + "...\t\t" + combinationTestsLoopsNb + "\t" + >+ (System.currentTimeMillis() - start)); >+ } >+ // PREMATURE optimize test (extraneous allocations and copies) >+ // PREMATURE optimize test (extraneous iterations - undup) >+ if (!skipHighOrderBits) { >+ UnconditionalFlowInfoTestHarness >+ zero = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.start), >+ left, right, left64, right64, left128, right128, >+ special = (UnconditionalFlowInfoTestHarness) zero.copy(); >+ special.grow(64); // allocates one extra without adding null info >+ transitionsSetsIterator = this.initializedTransitions.entrySet().iterator(); >+ while (transitionsSetsIterator.hasNext()) { >+ transitionsSet = (Map.Entry) transitionsSetsIterator.next(); >+ input1 = (State) transitionsSet.getKey(); >+ transitionsIterator = ((Map) transitionsSet.getValue()). >+ entrySet().iterator(); >+ while (transitionsIterator.hasNext()) { >+ transition = (Map.Entry) transitionsIterator.next(); >+ input2 = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ left = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input1); >+ left64 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input1, 64); >+ left128 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input1, 128); >+ right = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2); >+ right64 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2, 64); >+ right128 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2, 128); >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left64, right64)).asState(64)) != >+ expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if (input1 == State.start) { >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, right)).asState()) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 128, 1) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(zero, right64)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, right64)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 128, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(zero, right128)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero, 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right64, right128)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 64, 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(special, right128)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (special zero, 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ if (input2 == State.start) { >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left, left128)).asState()) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (1, zero 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left64, zero)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, zero) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left64, left128)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, zero 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left128, zero)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (128, zero) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left128, left64)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (128, zero 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ } >+ } >+ return this.failuresNb; >+} >+} >+ >+public abstract static class SymmetricalThreeDimensionalTransformation >+ extends ThreeDimensionalTransformation{ >+SymmetricalThreeDimensionalTransformation(String name, byte[][] transitions) { >+ super(name); >+ int length; >+ this.initializedTransitions = new HashMap((length = transitions.length) * 2 - 1); >+ State input1, input2; >+ for (int i = 0; i < length; i++) { >+ if (transitions[i].length != 3) { >+ throw new IllegalArgumentException("transitions should have three entries"); >+ } >+ if (transitions[i][0] <= transitions[i][1]) { >+ input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken >+ input2 = State.states[transitions[i][1]]; >+ } >+ else { >+ input1 = State.states[transitions[i][1]]; >+ input2 = State.states[transitions[i][0]]; >+ } >+ Map transitionsForInput1 = (Map) this.initializedTransitions.get(input1); >+ if (transitionsForInput1 == null) { >+ transitionsForInput1 = new HashMap(length); >+ this.initializedTransitions.put(input1, transitionsForInput1); >+ } >+ if (transitionsForInput1.get(input2) != null) { >+ throw new IllegalArgumentException("duplicate entry"); >+ } >+ transitionsForInput1.put(input2, State.states[transitions[i][2]]); >+ } >+} >+void hydrate() { >+ super.hydrate(); >+ checkSymmetry(this.computedTransitions); >+} >+private void checkSymmetry(Map map) { >+ State input1, input2, result; >+ Map.Entry entry1, entry2; >+ Map transition; >+ Iterator transitions1 = map.entrySet().iterator(), transitions2; >+ while (transitions1.hasNext()) { >+ entry1 = (Map.Entry) transitions1.next(); >+ input1 = (State) entry1.getKey(); >+ transition = (Map) entry1.getValue(); >+ transitions2 = transition.entrySet().iterator(); >+ while (transitions2.hasNext()) { >+ entry2 = (Map.Entry) transitions2.next(); >+ input2 = (State) entry2.getKey(); >+ result = (State) entry2.getValue(); >+ if (result != ((Map) map.get(input2)).get(input1) && input1.symbolic && input2.symbolic) { >+ System.err.println("symmetry mismatch: " + input1 + " + " + >+ input2 + " -> " + result + "/" + ((Map) map.get(input2)).get(input1)); >+ } >+ } >+ } >+} >+void mark(char truthValues[][], boolean keepRow[], boolean keepColumn[], >+ int row, int column, char value) { >+ truthValues[row][column] = truthValues[column][row] = value; >+ keepRow[row] = true; >+ keepColumn[column] = true; >+ keepRow[column] = true; >+ keepColumn[row] = true; >+} >+void printDefinitions(BufferedWriter output, State[] consideredStates, String tab) >+ throws IOException { >+ // only difference with parent is that we print only half of possible >+ // combinations >+ int i, j, length; >+ State result; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ for (j = i; j < length; j++) { >+ output.write(tab); >+ output.write("// "); >+ output.write(consideredStates[i].name); >+ output.write(" + "); >+ output.write(consideredStates[j].name); >+ output.write(" => "); >+ output.write( >+ (result = (State) >+ ((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name); >+ if (!result.symbolic || >+ result != this.initializedTransitions.get(consideredStates[i])) { >+ output.write("\t\t CHECK"); >+ } >+ output.write('\n'); >+ } >+ } >+} >+void printInitializers(BufferedWriter output, State[] consideredStates, String tab) >+ throws IOException { >+ // only difference with parent is that we print only half of possible >+ // combinations >+ int i, j, length; >+ for (i = 0, length = consideredStates.length; i < length; i++) { >+ for (j = i; j < length; j++) { >+ output.write(tab); >+ output.write('{'); >+ output.write(consideredStates[i].hexString); >+ output.write(','); >+ output.write(consideredStates[j].hexString); >+ output.write(','); >+ output.write( >+ ((State) >+ ((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).hexString); >+ output.write("},"); >+ output.write('\n'); >+ } >+ } >+} >+void printMissingEntries(BufferedWriter output, String tab) throws IOException { >+ Iterator firsts = State.symbolicStates(), seconds; >+ State first, second; >+ while (firsts.hasNext()) { >+ first = (State) firsts.next(); >+ seconds = State.symbolicStates(); >+ while (seconds.hasNext()) { >+ second = (State) seconds.next(); >+ if (!checkPair(first, second)) { >+ addPair(first, second); >+ System.err.println("Adding missing transition for states (" + first + ", " + second + ")"); >+ output.write(tab); >+ output.write("// "); >+ output.write(first.toString()); >+ output.write(" + "); >+ output.write(second.toString()); >+ output.write(" => start\t\t CHECK\n"); >+ } >+ } >+ } >+} >+private boolean checkPair(State s1, State s2) { >+ Map transitions; >+ if ((transitions = (Map) this.initializedTransitions.get(s1)) != null) { >+ if (transitions.get(s2) != null) { >+ return true; >+ } >+ } >+ if ((transitions = (Map) this.initializedTransitions.get(s2)) != null) { >+ if (transitions.get(s1) != null) { >+ return true; >+ } >+ } >+ return false; >+} >+private void addPair(State s1, State s2) { >+ Map transitions; >+ if ((transitions = (Map) this.initializedTransitions.get(s1)) == null) { >+ transitions = new HashMap(); >+ this.initializedTransitions.put(s1, transitions); >+ } >+ transitions.put(s2, s2); // dummy, non null value >+} >+// PREMATURE factorize upward >+int test(int combinationTestsLoopsNb, boolean skipHighOrderBits) { >+ Iterator transitionsSetsIterator, transitionsIterator; >+ State input1, input2, expectedOutput, effectiveOutput; >+ Map.Entry transition, transitionsSet; >+ this.failuresNb = 0; // reset >+ this.failuresNb = 0; // reset >+ long start = 0; >+ if (combinationTestsLoopsNb > 1) { >+ start = System.currentTimeMillis(); >+ } >+ for (int l = 0; l < combinationTestsLoopsNb ; l++) { >+ transitionsSetsIterator = this.initializedTransitions.entrySet().iterator(); >+ while (transitionsSetsIterator.hasNext()) { >+ transitionsSet = (Map.Entry) transitionsSetsIterator.next(); >+ input1 = (State) transitionsSet.getKey(); >+ transitionsIterator = ((Map) transitionsSet.getValue()). >+ entrySet().iterator(); >+ while (transitionsIterator.hasNext()) { >+ transition = (Map.Entry) transitionsIterator.next(); >+ input2 = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) output( >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1), >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2))) >+ .asState(); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " instead of: " + expectedOutput.printableBitsField); >+ } >+ effectiveOutput = ((UnconditionalFlowInfoTestHarness) output( >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2), >+ UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1))) >+ .asState(); >+ if (effectiveOutput != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ } >+ if (combinationTestsLoopsNb > 1) { >+ System.out.println(this.name + "...\t\t" + combinationTestsLoopsNb + "\t" + >+ (System.currentTimeMillis() - start)); >+ } >+ // PREMATURE optimize test (extraneous allocations and copies) >+ // PREMATURE optimize test (extraneous iterations - undup) >+ if (!skipHighOrderBits) { >+ UnconditionalFlowInfoTestHarness >+ zero = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.start), >+ right, left64, right64, right128; >+ transitionsSetsIterator = this.initializedTransitions.entrySet().iterator(); >+ while (transitionsSetsIterator.hasNext()) { >+ transitionsSet = (Map.Entry) transitionsSetsIterator.next(); >+ input1 = (State) transitionsSet.getKey(); >+ transitionsIterator = ((Map) transitionsSet.getValue()). >+ entrySet().iterator(); >+ while (transitionsIterator.hasNext()) { >+ transition = (Map.Entry) transitionsIterator.next(); >+ input2 = (State) transition.getKey(); >+ expectedOutput = (State) transition.getValue(); >+ left64 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input1, 64); >+ right = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2); >+ right64 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2, 64); >+ right128 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(input2, 128); >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(left64, right64)).asState(64)) != >+ expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right64, left64)).asState(64)) != >+ expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if (input1 == State.start) { >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, right)).asState()) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 128, 1) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(zero, right64)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, right64)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 128, 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(zero, right128)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero, 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right64, right128)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input1.printableBitsField + >+ " + " + input2.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (zero 64, 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right, right128)).asState()) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (1, zero 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right64, zero)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, zero) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right64, right128)).asState(64)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (64, zero 128) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, zero)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (128, zero) - instead of: " + expectedOutput.printableBitsField); >+ } >+ if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness) >+ output(right128, right64)).asState(128)) != expectedOutput) { >+ fail(); >+ System.out.println("\t\t" + input2.printableBitsField + >+ " + " + input1.printableBitsField + >+ " => " + effectiveOutput.printableBitsField + >+ " (128, zero 64) - instead of: " + expectedOutput.printableBitsField); >+ } >+ } >+ } >+ } >+ } >+ return this.failuresNb; >+} >+} >+} >Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java >=================================================================== >RCS file: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java >diff -N src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,1866 @@ >+/******************************************************************************* >+ * Copyright (c) 2005 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+import java.io.BufferedReader; >+import java.io.BufferedWriter; >+import java.io.File; >+import java.io.FileReader; >+import java.io.FileWriter; >+import java.io.IOException; >+import java.util.ArrayList; >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.List; >+import java.util.Map; >+import java.util.SortedMap; >+import java.util.TreeMap; >+ >+import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >+import org.eclipse.jdt.internal.compiler.flow.NullInfoRegistry; >+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; >+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo.AssertionFailedException; >+import org.eclipse.jdt.internal.compiler.impl.Constant; >+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; >+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >+ >+import junit.framework.AssertionFailedError; >+import junit.framework.Test; >+import junit.framework.TestSuite; >+ >+/** >+ * A tests series especially meant to validate the internals of our null >+ * reference analysis. See NullReferenceTest for tests targetted at >+ * the source code compiler behavior level. >+ */ >+public class NullReferenceImplTests extends NullReferenceTest { >+ // Static initializer to specify tests subset using TESTS_* static variables >+ // All specified tests which does not belong to the class are skipped... >+ // Only the highest compliance level is run; add the VM argument >+ // -Dcompliance=1.4 (for example) to lower it if needed >+ static { >+// TESTS_NAMES = new String[] { "test2050" }; >+// TESTS_NUMBERS = new int[] { 2061 }; >+// TESTS_NUMBERS = new int[] { 2999 }; >+// TESTS_RANGE = new int[] { 2050, -1 }; >+ } >+ >+/** >+ * A class to hold states as seen by the low level validation tests and machinery. >+ * State provides: >+ * - singletons for all possible states given the number of bits for the said >+ * states; >+ * - semantic names for known states; >+ * - printable representation of states as bit fields; >+ * - coordination with other classes to perform transitive closure analysis, etc. >+ */ >+ /* >+ This is a tabular definition for states. It can be completed/leveraged by >+ the Generator class so as to smoothen the transition between differing encodings >+ of the states. >+ // STATES DEFINITION START >+ 000000 start >+ 000001 >+ 000010 >+ 000011 >+ 000100 pot. unknown >+ 000101 >+ 000110 >+ 000111 >+ 001000 pot. non null >+ 001001 >+ 001010 >+ 001011 >+ 001100 pot. nn & pot. un >+ 001101 >+ 001110 >+ 001111 >+ 010000 pot. null >+ 010001 >+ 010010 >+ 010011 >+ 010100 pot. n & pot. un >+ 010101 >+ 010110 >+ 010111 >+ 011000 pot. n & pot. nn >+ 011001 >+ 011010 >+ 011011 >+ 011100 >+ 011101 >+ 011110 >+ 011111 >+ 100000 >+ 100001 >+ 100010 >+ 100011 >+ 100100 def. unknown >+ 100101 >+ 100110 >+ 100111 >+ 101000 def. non null >+ 101001 >+ 101010 >+ 101011 >+ 101100 pot. nn & prot. nn >+ 101101 >+ 101110 >+ 101111 >+ 110000 def. null >+ 110001 >+ 110010 >+ 110011 >+ 110100 pot. n & prot. n >+ 110101 >+ 110110 >+ 110111 >+ 111000 prot. null >+ 111001 >+ 111010 >+ 111011 >+ 111100 prot. non null >+ 111101 >+ 111110 >+ 111111 >+ // STATES DEFINITION END >+ */ >+ public static class State implements Comparable { >+ // PREMATURE consider moving initialization to test setup/dispose >+ public final static State[] states = { >+ // STATES INITIALIZER START >+ new State(0, "start"), // 000000 >+ new State(1), // 000001 >+ new State(2), // 000010 >+ new State(3), // 000011 >+ new State(4, "pot. unknown"), // 000100 >+ new State(5), // 000101 >+ new State(6), // 000110 >+ new State(7), // 000111 >+ new State(8, "pot. non null"), // 001000 >+ new State(9), // 001001 >+ new State(10), // 001010 >+ new State(11), // 001011 >+ new State(12, "pot. nn & pot. un"), // 001100 >+ new State(13), // 001101 >+ new State(14), // 001110 >+ new State(15), // 001111 >+ new State(16, "pot. null"), // 010000 >+ new State(17), // 010001 >+ new State(18), // 010010 >+ new State(19), // 010011 >+ new State(20, "pot. n & pot. un"), // 010100 >+ new State(21), // 010101 >+ new State(22), // 010110 >+ new State(23), // 010111 >+ new State(24, "pot. n & pot. nn"), // 011000 >+ new State(25), // 011001 >+ new State(26), // 011010 >+ new State(27), // 011011 >+ new State(28), // 011100 >+ new State(29), // 011101 >+ new State(30), // 011110 >+ new State(31), // 011111 >+ new State(32), // 100000 >+ new State(33), // 100001 >+ new State(34), // 100010 >+ new State(35), // 100011 >+ new State(36, "def. unknown"), // 100100 >+ new State(37), // 100101 >+ new State(38), // 100110 >+ new State(39), // 100111 >+ new State(40, "def. non null"), // 101000 >+ new State(41), // 101001 >+ new State(42), // 101010 >+ new State(43), // 101011 >+ new State(44, "pot. nn & prot. nn"), // 101100 >+ new State(45), // 101101 >+ new State(46), // 101110 >+ new State(47), // 101111 >+ new State(48, "def. null"), // 110000 >+ new State(49), // 110001 >+ new State(50), // 110010 >+ new State(51), // 110011 >+ new State(52, "pot. n & prot. n"), // 110100 >+ new State(53), // 110101 >+ new State(54), // 110110 >+ new State(55), // 110111 >+ new State(56, "prot. null"), // 111000 >+ new State(57), // 111001 >+ new State(58), // 111010 >+ new State(59), // 111011 >+ new State(60, "prot. non null"), // 111100 >+ new State(61), // 111101 >+ new State(62), // 111110 >+ new State(63), // 111111 >+ // STATES INITIALIZER END >+ }; >+ public final static State start = states[0]; >+ public static final int >+ stateMaxValue = 0x3F, >+ stateWidth = 6, >+ statesNb = stateMaxValue + 1; >+ String name, printableBitsField, hexString; >+ public byte value; >+ boolean symbolic; >+ private State() { >+ } >+ private State(int numericValue) { >+ this(numericValue, null); >+ } >+ private State(int numericValue, String publicName) { >+ if (numericValue > stateMaxValue) { >+ throw new IllegalArgumentException("state value overflow"); >+ } >+ this.value = (byte) numericValue; >+ StringBuffer printableValue = new StringBuffer(6); >+ for (int i = stateWidth - 1; i >= 0; i--) { >+ printableValue.append((numericValue >>> i & 1) != 0 ? '1' : '0'); >+ } >+ this.printableBitsField = printableValue.toString(); >+ if (this.value > 0xF) { >+ this.hexString = "0x" + Integer.toHexString(this.value).toUpperCase(); >+ } >+ else { >+ this.hexString = "0x0" + Integer.toHexString(this.value).toUpperCase(); >+ } >+ if (publicName != null) { >+ this.name = publicName; >+ this.symbolic = true; >+ } >+ else { >+ this.name = this.printableBitsField; >+ } >+ } >+ private State(String commentLine) { >+ char current = ' '; // keep the initialization status quiet >+ int cursor, length; >+ for (cursor = 0, length = commentLine.length(); >+ cursor < length; >+ cursor++) { >+ if ((current = commentLine.charAt(cursor)) == '0' || >+ current == '1') { >+ break; >+ } >+ } >+ if (cursor == length) { >+ throw new RuntimeException("bad state definition format (missing bits field): " + commentLine); >+ // PREMATURE adopt consistent error policy >+ } >+ int valueDigits; >+ for (valueDigits = 1; cursor < (length - 1) && valueDigits < stateWidth; valueDigits++) { >+ this.value = (byte) ((this.value << 1) + (current - '0')); >+ if ((current = commentLine.charAt(++cursor)) != '0' && >+ current != '1') { >+ throw new RuntimeException("bad state definition format (inappropriate character in bits field): " + commentLine); >+ // PREMATURE adopt consistent error policy >+ } >+ } >+ if (valueDigits < stateWidth) { >+ throw new RuntimeException("bad state definition format (bits field is too short): " + commentLine); >+ // PREMATURE adopt consistent error policy >+ } >+ this.value = (byte) ((this.value << 1) + (current - '0')); >+ this.printableBitsField = commentLine.substring(cursor - stateWidth + 1, cursor + 1); >+ if (this.value > 0xF) { >+ this.hexString = "0x" + Integer.toHexString(this.value).toUpperCase(); >+ } >+ else { >+ this.hexString = "0x0" + Integer.toHexString(this.value).toUpperCase(); >+ } >+ while (++cursor < length && Character.isWhitespace(current = commentLine.charAt(++cursor)) && current != '\n') { >+ // loop >+ } >+ if (cursor < length && current != '\n') { >+ this.name = commentLine.substring(cursor, length); >+ } >+ if (this.name == null) { >+ this.name = this.printableBitsField; >+ } else { >+ this.symbolic = true; >+ } >+ } >+ private String asInitializer() { >+ StringBuffer result = new StringBuffer(70); >+ result.append(" new State("); >+ result.append(this.value); >+ char first; >+ boolean nameIsSymbolic = (first = this.name.charAt(0)) != '0' >+ && first != '1'; >+ if (nameIsSymbolic) { >+ result.append(", \""); >+ result.append(this.name); >+ result.append('"'); >+ } >+ result.append("), // "); >+ result.append(this.printableBitsField); >+ return result.toString(); >+ } >+ long [] asLongArray() { >+ long[] result = new long[stateWidth]; >+ for (int i = 0; i < stateWidth; i++) { >+ result[i] = ((this.value >> (stateWidth - i - 1)) & 1) == 0 ? 0 : 1; >+ } >+ return result; >+ } >+ private String asSourceComment() { >+ StringBuffer result = new StringBuffer(70); >+ result.append("\t\t"); >+ result.append(this.printableBitsField); >+ char first; >+ boolean nameIsSymbolic = (first = this.name.charAt(0)) != '0' >+ && first != '1'; >+ if (nameIsSymbolic) { >+ result.append('\t'); >+ result.append(this.name); >+ } >+ return result.toString(); >+ } >+ public int compareTo(Object o) { >+ return this.value - ((State) o).value; >+ } >+ static State fromLongValues(long bit1, long bit2, long bit3, long bit4, long bit5, long bit6) { >+ // PREMATURE consider taking an UnconditionalFlowInfo in parameter >+ return states[(int)( >+ (bit6 & 1) + >+ 2 * ((bit5 & 1) + >+ 2 * ((bit4 & 1) + >+ 2 * ((bit3 & 1) + >+ 2 * ((bit2 & 1) + >+ 2 * (bit1 & 1))))))]; >+ } >+ private static Map namesIndex; >+ static State fromSymbolicName (String name) { >+ if (namesIndex == null) { >+ namesIndex = new HashMap(states.length); >+ for (int i = 0; i < states.length; i++) { >+ if (states[i].name != null) { >+ namesIndex.put(states[i].name, states[i]); >+ } >+ } >+ } >+ return (State) namesIndex.get(name); >+ } >+ private static void grabDefinitionFromComment(BufferedReader input) { >+ String line; >+ State current; >+ // use when the initializer is incomplete, hence needs to be reinitialized >+ // states = new State[stateMaxValue + 1]; >+ // use when the states field is final, with the appropriate size: >+ for (int i = 0; i <= stateMaxValue; i++) { >+ states[i] = null; >+ } >+ try { >+ while ((line = input.readLine()) != null && line.indexOf(definitionEndMarker) == -1) { >+ current = new State(line); >+ if (states[current.value] != null) { >+ throw new RuntimeException("duplicate state for index: " + current.value); >+ } >+ else { >+ states[current.value] = current; >+ } >+ } >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+ for (int i = 0; i < stateMaxValue; i++) { >+ if (states[i] == null) { >+ states[i] = new State(i); >+ } >+ } >+ } >+ // PREMATURE may decide to remove >+ //private static void printAsInitializer() { >+ // int i, length; >+ // System.out.println(initializerStartMarker); >+ // for (i = 0, length = states.length; i < length; i++) { >+ // System.out.println(states[i].asInitializer()); >+ // } >+ // for (/* continue */; i <= stateMaxValue; i++) { >+ // System.out.println((new State(i)).asInitializer() + " CHECK"); >+ // } >+ // System.out.println(initializerEndMarker); >+ //} >+ // PREMATURE may decide to remove >+ //private static void printAsSourceComment() { >+ // int i, length; >+ // System.out.println("/*"); >+ // System.out.println(definitionStartMarker); >+ // for (i = 0, length = states.length; i < length; i++) { >+ // System.out.println(states[i].asSourceComment()); >+ // } >+ // for (/* continue */; i <= stateMaxValue; i++) { >+ // System.out.println((new State(i)).asSourceComment()); >+ // } >+ // System.out.println(definitionEndMarker); >+ // System.out.println("*/"); >+ //} >+ private final static String >+ definitionStartMarker = "// STATES " + CodeAnalysis.definitionStartMarker, >+ definitionEndMarker = "// STATES " + CodeAnalysis.definitionEndMarker, >+ initializerStartMarker = "// STATES " + CodeAnalysis.initializerStartMarker, >+ initializerEndMarker = "// STATES " + CodeAnalysis.initializerEndMarker; >+ static void reinitializeFromComment(BufferedReader input, BufferedWriter output) { >+ String line, tab = ""; >+ int cursor; >+ char c; >+ try { >+ while ((line = input.readLine()) != null) { >+ output.write(line); >+ output.write('\n'); >+ if ((cursor = line.indexOf(definitionStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ grabDefinitionFromComment(input); // consumes up to the END line >+ int i, length; >+ for (i = 0, length = states.length; i < length; i++) { >+ output.write(states[i].asSourceComment()); >+ output.write('\n'); >+ } >+ output.write(tab + definitionEndMarker + "\n"); >+ } >+ } >+ if ((cursor = line.indexOf(initializerStartMarker)) != -1) { >+ // check the line format >+ boolean reachedStart = true; >+ tab = ""; >+ for (int i = 0; i < cursor; i++) { >+ if (!Character.isWhitespace(c = line.charAt(i))) { >+ reachedStart = false; >+ break; >+ } >+ else { >+ tab += c; >+ } >+ } >+ if (reachedStart) { >+ while ((line = input.readLine()) != null && >+ line.indexOf(initializerEndMarker) == -1) { >+ // loop >+ } >+ int i, length; >+ for (i = 0, length = states.length; i < length; i++) { >+ output.write(states[i].asInitializer()); >+ output.write('\n'); >+ } >+ output.write(tab + initializerEndMarker + "\n"); >+ } >+ } >+ } >+ output.flush(); >+ namesIndex = null; >+ } catch (IOException e) { >+ throw new RuntimeException(e); >+ } >+ } >+ static Iterator symbolicStates() { >+ return new Iterator() { >+ int nextSymbolic = -1; >+ public boolean hasNext() { >+ if (nextSymbolic == -1) { >+ for (nextSymbolic = 0; nextSymbolic < states.length; nextSymbolic++) { >+ if (states[nextSymbolic].symbolic) { >+ break; >+ } >+ } >+ } else { >+ for (; nextSymbolic < states.length; nextSymbolic++) { >+ if (states[nextSymbolic].symbolic) { >+ break; >+ } >+ } >+ } >+ return nextSymbolic < states.length; >+ } >+ public Object next() { >+ State result = null; >+ if (nextSymbolic < states.length) { >+ result = states[nextSymbolic]; >+ nextSymbolic++; >+ } >+ return result; >+ } >+ public void remove() { >+ throw new RuntimeException("unimplemented"); >+ } >+ }; >+ } >+ public String toString() { >+ return this.name; >+ } >+ } >+ >+public NullReferenceImplTests(String name) { >+ super(name); >+} >+ >+ // Tests tuning >+ static final boolean >+ skipHighOrderBits = false; // define to true when tuning encoding >+ static final int >+ combinationTestsloopsNb = 1; // define to 10000s to measure performances >+ >+public static Test suite() { >+ // we do not want to run for 1.3, 1.4, 1.5 but once only >+ Class clazz = testClass(); >+ TestSuite all = new TestSuite(clazz.getName()); >+ List tests = buildTestsList(testClass()); >+ for (int i = 0, length = tests.size(); i < length; i++) { >+ all.addTest((Test) tests.get(i)); >+ } >+ return all; >+} >+ >+public static Class testClass() { >+ return NullReferenceImplTests.class; >+} >+ >+public void test2050_markAsComparedEqualToNonNull() { >+ int failures = NullReferenceImplTransformations.markAsComparedEqualToNonNull.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2051_markAsComparedEqualToNull() { >+ int failures = NullReferenceImplTransformations.markAsComparedEqualToNull.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2055_markAsDefinitelyNonNull() { >+ int failures = NullReferenceImplTransformations.markAsDefinitelyNonNull.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2056_markAsDefinitelyNull() { >+ int failures = NullReferenceImplTransformations.markAsDefinitelyNull.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2057_markAsDefinitelyUnknown() { >+ int failures = NullReferenceImplTransformations.markAsDefinitelyUnknown.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2060_addInitializationsFrom() { >+ int failures = NullReferenceImplTransformations.addInitializationsFrom.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2061_addPotentialInitializationsFrom() { >+ int failures = NullReferenceImplTransformations.addPotentialInitializationsFrom.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2062_mergedWith() { >+ int failures = NullReferenceImplTransformations.mergedWith.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2070_newNullInfoRegistry() { >+ int failures = NullReferenceImplTransformations.newNullInfoRegistry.test(); >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+// PREMATURE rewrite from scratch >+//public void _test2058_recode() { >+// long [][][] testData = transitionsTablesData[recode]; >+// int failures = 0; >+// long start; >+// if (combinationTestsloopsNb > 1) { >+// start = System.currentTimeMillis(); >+// } >+// String header = "recode failures: "; >+// for (int l = 0; l < combinationTestsloopsNb ; l++) { >+// for (int i = 0; i < testData.length; i++) { >+// UnconditionalFlowInfoTestHarness result; >+// result = UnconditionalFlowInfoTestHarness. >+// testUnconditionalFlowInfo(testData[i][0]); >+// result.encode(); >+// result.decode(); >+// >+// if (!result.testEquals(UnconditionalFlowInfoTestHarness. >+// testUnconditionalFlowInfo(testData[i][0]))) { >+// if (failures == 0) { >+// System.out.println(header); >+// } >+// failures++; >+// System.out.println("\t\t{" + result.testString() + >+// "}, // instead of: " + testStringValueOf(testData[i][0])); >+// } >+// } >+// } >+// if (combinationTestsloopsNb > 1) { >+// System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" + >+// (System.currentTimeMillis() - start)); >+// } >+// for (int i = 0; i < testData.length; i++) { >+// UnconditionalFlowInfoTestHarness result; >+// result = UnconditionalFlowInfoTestHarness. >+// testUnconditionalFlowInfo(testData[i][0], 64); >+// result.encode(); >+// result.decode(); >+// >+// if (!result.testEquals(UnconditionalFlowInfoTestHarness. >+// testUnconditionalFlowInfo(testData[i][0], 64))) { >+// if (failures == 0) { >+// System.out.println(header); >+// } >+// failures++; >+// System.out.println("\t\t{" + result.testString() + >+// "}, // (64) - instead of: " + testStringValueOf(testData[i][0])); >+// } >+// } >+// assertTrue("nb of failures: " + failures, failures == 0); >+//} >+ >+public void test2400_state_consistency() { >+ int failures = 0; >+ long start; >+ if (combinationTestsloopsNb > 1) { >+ start = System.currentTimeMillis(); >+ } >+ String header = "state consistency failures: "; >+ for (int l = 0; l < combinationTestsloopsNb ; l++) { >+ for (int i = 0; i < State.states.length; i++) { >+ if (State.states[i].symbolic) { >+ UnconditionalFlowInfoTestHarness >+ state = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.states[i]); >+ boolean >+ isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local0), >+ isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local0), >+ isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local0), >+ isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0), >+ isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0), >+ isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0), >+ isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0); >+ if (isDefinitelyNonNull >+ && (isDefinitelyNull || isDefinitelyUnknown >+ || isPotentiallyNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage for definitely non null state " + State.states[i].name); >+ } >+ if (isDefinitelyNull >+ && (isDefinitelyNonNull || isDefinitelyUnknown >+ || isPotentiallyUnknown || isProtectedNonNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage for definitely null state " + State.states[i].name); >+ } >+ if (isDefinitelyUnknown >+ && (isDefinitelyNonNull || isDefinitelyNull >+ || isPotentiallyNull || isProtectedNonNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage for definitely unknown state " + State.states[i].name); >+ } >+ if (isProtectedNonNull && !isDefinitelyNonNull >+ || isProtectedNull && !isDefinitelyNull >+ || i > 0 // not start >+ && !State.states[i].name.equals("pot. non null") >+ && !(isDefinitelyNonNull || isDefinitelyNull >+ || isDefinitelyUnknown || isPotentiallyNull >+ || isPotentiallyUnknown || isProtectedNonNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage for " + State.states[i].name); >+ } >+ } >+ } >+ } >+ if (combinationTestsloopsNb > 1) { >+ System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" + >+ (System.currentTimeMillis() - start)); >+ } >+ for (int i = 0; i < State.states.length; i++) { >+ if (State.states[i].symbolic) { >+ UnconditionalFlowInfoTestHarness state; >+ state = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.states[i], 64); >+ boolean >+ isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local64), >+ isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local64), >+ isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local64), >+ isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64), >+ isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64), >+ isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64), >+ isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64); >+ if (isDefinitelyNonNull >+ && (isDefinitelyNull || isDefinitelyUnknown >+ || isPotentiallyNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage (64) for definitely non null state " + State.states[i].name); >+ } >+ if (isDefinitelyNull >+ && (isDefinitelyNonNull || isDefinitelyUnknown >+ || isPotentiallyUnknown || isProtectedNonNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage (64) for definitely null state " + State.states[i].name); >+ } >+ if (isDefinitelyUnknown >+ && (isDefinitelyNonNull || isDefinitelyNull >+ || isPotentiallyNull || isProtectedNonNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage (64) for definitely unknown state " + State.states[i].name); >+ } >+ if (isProtectedNonNull && !isDefinitelyNonNull >+ || isProtectedNull && !isDefinitelyNull >+ || i > 0 // not start >+ && !State.states[i].name.equals("pot. non null") >+ && !(isDefinitelyNonNull || isDefinitelyNull >+ || isDefinitelyUnknown || isPotentiallyNull >+ || isPotentiallyUnknown || isProtectedNonNull >+ || isProtectedNull)) { >+ if (failures == 0) { >+ System.out.println(header); >+ } >+ failures++; >+ System.out.println("\t\tconsistency breakage (64) for " + State.states[i].name); >+ } >+ } >+ } >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+public void test2500_addInitializationsFrom_for_definites() { >+ // when an added initialization is a def. something, it should >+ // affect the left hand term as the markAsDefinite* method would >+ // do >+ int failures = 0; >+ for (int i = 0; i < State.states.length; i++) { >+ if (State.states[i].symbolic) { >+ UnconditionalFlowInfoTestHarness source1, source2, result1, result2; >+ source1 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.states[i]); >+ for (int j = 0; j < State.states.length; j++) { >+ if (State.states[j].symbolic) { >+ source2 = UnconditionalFlowInfoTestHarness. >+ testUnconditionalFlowInfo(State.states[j]); >+ result1 = (UnconditionalFlowInfoTestHarness) source1.copy(); >+ result2 = (UnconditionalFlowInfoTestHarness) source1.copy(); >+ if (source2.isDefinitelyNonNull(TestLocalVariableBinding.local0)) { >+ if (! source2.isProtectedNonNull(TestLocalVariableBinding.local0)) { >+ result1.markAsDefinitelyNonNull(TestLocalVariableBinding.local0); >+ } else { >+ continue; >+ } >+ } >+ else if (source2.isDefinitelyNull(TestLocalVariableBinding.local0)) { >+ if (! source2.isProtectedNull(TestLocalVariableBinding.local0)) { >+ result1.markAsDefinitelyNull(TestLocalVariableBinding.local0); >+ } else { >+ continue; >+ } >+ } >+ else if (source2.isDefinitelyUnknown(TestLocalVariableBinding.local0)) { >+ result1.markAsDefinitelyUnknown(TestLocalVariableBinding.local0); >+ } >+ else if (source2.nullBit1 != 0) { >+ if (failures == 0) { >+ System.out.println("addInitializationsFrom_for_definites failures: "); //$NON-NLS-1$ >+ } >+ failures++; >+ System.out.println("\t\t" + State.states[j].name + >+ " should answer true to at least one isDefinite* query"); >+ // PREMATURE move to specific queries test case >+ } >+ else { >+ continue; >+ } >+ result2.addInitializationsFrom(source2); >+ if (!result1.testEquals(result2)) { >+ if (failures == 0) { >+ System.out.println("addInitializationsFrom_for_definites failures: "); //$NON-NLS-1$ >+ } >+ failures++; >+ System.out.println("\t\t" + State.states[i].name + >+ " + " + State.states[j].name + >+ " => " + result2.asState().name + >+ " instead of: " + result1.asState().name); >+ } >+ } >+ } >+ } >+ } >+ assertTrue("nb of failures: " + failures, failures == 0); >+} >+ >+// Use for coverage tests only. Needs specific instrumentation of code, >+// that is controled by UnconditionalFlowInfo#coverageTestFlag. >+// 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 = 39; >+ >+// PREMATURE reactivate coverage tests >+// Coverage by state transition tables methods. >+public void test2998_coverage() { >+ if (UnconditionalFlowInfo.coverageTestFlag) { >+ // sanity check: need to be sure that the tests execute properly when not >+ // trying to check coverage >+ UnconditionalFlowInfo.coverageTestId = 0; >+ test0053_array(); >+ test0070_type_reference(); >+ test2050_markAsComparedEqualToNonNull(); >+ test2051_markAsComparedEqualToNull(); >+ test2055_markAsDefinitelyNonNull(); >+ test2056_markAsDefinitelyNull(); >+ test2057_markAsDefinitelyUnknown(); >+ test2060_addInitializationsFrom(); >+ test2061_addPotentialInitializationsFrom(); >+ test2062_mergedWith(); >+ // coverage check >+ int failuresNb = 0; >+ for (int i = 1; i <= coveragePointsNb; i++) { >+ if (i == 11 || i == 12 || i == 14) { >+ continue; >+ // these can only be reached via a direct call to addPotentialNullInfoFrom, >+ // which is not implemented in low level tests - all those go through >+ // addPotentialInitsFrom >+ } >+ try { >+ UnconditionalFlowInfo.coverageTestId = i; >+ test0053_array(); >+ test0070_type_reference(); >+ test2050_markAsComparedEqualToNonNull(); >+ test2051_markAsComparedEqualToNull(); >+ test2055_markAsDefinitelyNonNull(); >+ test2056_markAsDefinitelyNull(); >+ test2057_markAsDefinitelyUnknown(); >+ test2060_addInitializationsFrom(); >+ test2061_addPotentialInitializationsFrom(); >+ test2062_mergedWith(); >+ } >+ catch (AssertionFailedError e) { >+ continue; >+ } >+ catch (AssertionFailedException e) { >+ continue; >+ } >+ failuresNb++; >+ System.out.println("Missing coverage point: " + i); >+ } >+ UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests >+ assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); >+ } >+} >+ >+// Coverage by code samples. >+public void test2999_coverage() { >+ if (UnconditionalFlowInfo.coverageTestFlag) { >+ // sanity check: need to be sure that the tests execute properly when not >+ // trying to check coverage >+ UnconditionalFlowInfo.coverageTestId = 0; >+ test0001_simple_local(); >+ test0053_array(); >+ test0070_type_reference(); >+ test0327_if_else(); >+ test0401_while(); >+ test0420_while(); >+ test0509_try_finally_embedded(); >+ test2000_flow_info(); >+ test2004_flow_info(); >+ test2008_flow_info(); >+ test2011_flow_info(); >+ test2013_flow_info(); >+ test2018_flow_info(); >+ test2019_flow_info(); >+ test2020_flow_info(); >+ // coverage check >+ int failuresNb = 0; >+ for (int i = 1; i <= coveragePointsNb; i++) { >+ if (i < 3 >+ || 4 < i && i < 11 >+ || 11 < i && i < 16 >+ || 16 < i && i < 20 >+ || i == 21 >+ || 23 < i && i < 27 >+ || 29 < i && i < 33 >+ || 36 < i) { // TODO (maxime) complete coverage tests >+ continue; >+ } >+ try { >+ UnconditionalFlowInfo.coverageTestId = i; >+ test0001_simple_local(); >+ test0053_array(); >+ test0070_type_reference(); >+ test0327_if_else(); >+ test0401_while(); >+ test0420_while(); >+ test0509_try_finally_embedded(); >+ test2000_flow_info(); >+ test2004_flow_info(); >+ test2008_flow_info(); >+ test2011_flow_info(); >+ test2013_flow_info(); >+ test2018_flow_info(); >+ test2019_flow_info(); >+ test2020_flow_info(); >+ } >+ catch (AssertionFailedError e) { >+ continue; >+ } >+ catch (AssertionFailedException e) { >+ continue; >+ } >+ failuresNb++; >+ System.out.println("Missing coverage point: " + i); >+ } >+ UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests >+ assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); >+ } >+} >+ >+// only works for info coded on bit 0 - least significant >+String testCodedValueOf(long[] data) { >+ int length; >+ StringBuffer result = new StringBuffer(length = data.length); >+ for (int i = 0; i < length; i++) { >+ result.append(data[i] == 0 ? '0' : '1'); >+ } >+ return result.toString(); >+} >+ >+static String testStringValueOf(long[] data) { >+ int length; >+ StringBuffer result = new StringBuffer((length = data.length) * 2 + 1); >+ result.append('{'); >+ for (int i = 0; i < length; i++) { >+ if (i > 0) { >+ result.append(','); >+ } >+ result.append(data[i]); >+ } >+ result.append('}'); >+ return result.toString(); >+} >+} >+ >+/** >+ * A specific extension of LocalVariableBinding suitable for flow info >+ * manipulation at an implementation level. >+ */ >+class TestLocalVariableBinding extends LocalVariableBinding { >+ static class TestTypeBinding extends TypeBinding { >+ public TestTypeBinding() { >+ tagBits = 0L; >+ } >+ public char[] constantPoolName() { >+ return null; >+ } >+ public PackageBinding getPackage() { >+ return null; >+ } >+ public boolean isCompatibleWith(TypeBinding right) { >+ return false; >+ } >+ public char[] qualifiedSourceName() { >+ return null; >+ } >+ public char[] sourceName() { >+ return null; >+ } >+ public char[] readableName() { >+ return null; >+ } >+ } >+ final static TypeBinding testTypeBinding = new TestTypeBinding(); >+ final static char [] testName = {'t', 'e', 's', 't'}; >+ TestLocalVariableBinding(int id) { >+ super(testName, testTypeBinding, 0, false); >+ this.id = id; >+ } >+ public Constant constant() { >+ return Constant.NotAConstant; >+ } >+ static final TestLocalVariableBinding >+ local0 = new TestLocalVariableBinding(0), >+ local64 = new TestLocalVariableBinding(64), >+ local128 = new TestLocalVariableBinding(128); >+} >+ >+/** >+ * A class meant to augment >+ * @link{org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo} with >+ * capabilities in the test domain. It especially provides factories to build >+ * fake flow info instances for use in state transitions validation. >+ */ >+/* >+ * Moreover, this class defines the implementation of key operations for the >+ * benefit of itself and NullInfoRegistryTestHarness. Given the fact that the >+ * latter could not extend UnconditionalFlowInfoTestHarness and >+ * NullInfoRegistry, the code is factorized into static methods. >+ */ >+class UnconditionalFlowInfoTestHarness extends UnconditionalFlowInfo { >+ int testPosition; >+ // Interface >+/** >+ * Return the state represented by this. >+ * @return the state represented by this >+ */ >+NullReferenceImplTests.State asState() { >+ return asState(this, 0); >+} >+ >+/** >+ * Return the state represented by this for a variable encoded at a given position. >+ * @param position - int the position of the considered variable >+ * @return the state represented by this for a variable encoded at a given position >+ */ >+NullReferenceImplTests.State asState(int position) { >+ return asState(this, position); >+} >+ >+public FlowInfo copy() { >+ UnconditionalFlowInfoTestHarness copy = >+ new UnconditionalFlowInfoTestHarness(); >+ copy.testPosition = this.testPosition; >+ copy(this, copy); >+ return copy; >+} >+ >+public void markAsDefinitelyNonNull(LocalVariableBinding local) { >+ grow(local.id + this.maxFieldCount); >+ super.markAsDefinitelyNonNull(local); >+} >+ >+public void markAsDefinitelyNull(LocalVariableBinding local) { >+ grow(local.id + this.maxFieldCount); >+ super.markAsDefinitelyNull(local); >+} >+ >+public void markAsDefinitelyUnknown(LocalVariableBinding local) { >+ grow(local.id + this.maxFieldCount); >+ super.markAsDefinitelyUnknown(local); >+} >+ >+/** >+ * Return a fake unconditional flow info which bit fields represent the given >+ * null bits for a local variable of id 0 within a class that would have no >+ * field. >+ * @param nullBits the bits that must be set, given in the same order as the >+ * nullAssignment* fields in UnconditionalFlowInfo definition; use 0 >+ * for a bit that is not set, 1 else >+ * @return a fake unconditional flow info which bit fields represent the >+ * null bits given in parameter >+ */ >+public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >+ long [] nullBits) { >+ return testUnconditionalFlowInfo(nullBits, 0); >+} >+ >+/** >+ * Return a fake unconditional flow info which bit fields represent the given >+ * null bits for a local variable of id position within a class that would have >+ * no field. >+ * @param nullBits the bits that must be set, given in the same order as the >+ * nullAssignment* fields in UnconditionalFlowInfo definition; use 0 >+ * for a bit that is not set, 1 else >+ * @param position the position of the variable within the bit fields; use >+ * various values to test different parts of the bit fields, within >+ * or beyond BitCacheSize >+ * @return a fake unconditional flow info which bit fields represent the >+ * null bits given in parameter >+ */ >+public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >+ long [] nullBits, int position) { >+ UnconditionalFlowInfoTestHarness result = >+ new UnconditionalFlowInfoTestHarness(); >+ result.testPosition = position; >+ init(result, nullBits, position); >+ return result; >+} >+ >+/** >+ * Return a fake unconditional flow info which bit fields represent the given >+ * state for a local variable of id 0 within a class that would have >+ * no field. >+ * @param state - State the desired state for the variable >+ * @return a fake unconditional flow info which bit fields represent the >+ * state given in parameter >+ */ >+public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo(NullReferenceImplTests.State state) { >+ return testUnconditionalFlowInfo(state, 0); >+} >+ >+/** >+ * Return a fake unconditional flow info which bit fields represent the given >+ * state for a local variable of id position within a class that would have >+ * no field. >+ * @param state - State the desired state for the variable >+ * @param position the position of the variable within the bit fields; use >+ * various values to test different parts of the bit fields, within >+ * or beyond BitCacheSize >+ * @return a fake unconditional flow info which bit fields represent the >+ * state given in parameter >+ */ >+public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( >+ NullReferenceImplTests.State state, int position) { >+ UnconditionalFlowInfoTestHarness result = >+ new UnconditionalFlowInfoTestHarness(); >+ long[] nullBits = state.asLongArray(); >+ result.testPosition = position; >+ init(result, nullBits, position); >+ return result; >+} >+ >+/** >+ * Return true iff this flow info can be considered as equal to the one passed >+ * in parameter. >+ * @param other the flow info to compare to >+ * @return true iff this flow info compares equal to other >+ */ >+public boolean testEquals(UnconditionalFlowInfo other) { >+ return testEquals(this, other); >+} >+ >+/** >+ * Return true iff this flow info can be considered as equal to the one passed >+ * in parameter in respect with a single local variable which id would be >+ * position in a class with no field. >+ * @param other the flow info to compare to >+ * @param position the position of the local to consider >+ * @return true iff this flow info compares equal to other for a given local >+ */ >+public boolean testEquals(UnconditionalFlowInfo other, int position) { >+ return testEquals(this, other, position); >+} >+ >+/** >+ * Return a string suitable for use as a representation of this flow info >+ * within test series. >+ * @return a string suitable for use as a representation of this flow info >+ */ >+public String testString() { >+ if (this == DEAD_END) { >+ return "FlowInfo.DEAD_END"; //$NON-NLS-1$ >+ } >+ return testString(this, this.testPosition); >+} >+ >+/** >+ * Return a string suitable for use as a representation of this flow info >+ * within test series. >+ * @param position a position to consider instead of this flow info default >+ * test position >+ * @return a string suitable for use as a representation of this flow info >+ */ >+public String testString(int position) { >+ return testString(this, position); >+} >+ >+ // Factorized implementation >+static NullReferenceImplTests.State asState(UnconditionalFlowInfo zis, int position) { >+ if ((zis.tagBits & NULL_FLAG_MASK) == 0) { >+ return NullReferenceImplTests.State.start; >+ } >+ if (position < BitCacheSize) { >+ return NullReferenceImplTests.State.fromLongValues( >+ (zis.nullBit1 >> position) & 1, >+ (zis.nullBit2 >> position) & 1, >+ (zis.nullBit3 >> position) & 1, >+ (zis.nullBit4 >> position) & 1, >+ 0, >+ 0); >+ } >+ else { >+ int vectorIndex = (position / BitCacheSize) - 1; >+ position %= BitCacheSize; >+ if (vectorIndex >= zis.extra[2].length) { >+ return NullReferenceImplTests.State.start; >+ } >+ return NullReferenceImplTests.State.fromLongValues( >+ (zis.extra[2][vectorIndex] >> position) & 1, >+ (zis.extra[3][vectorIndex] >> position) & 1, >+ (zis.extra[4][vectorIndex] >> position) & 1, >+ (zis.extra[5][vectorIndex] >> position) & 1, >+ 0 //(zis.extra[6][vectorIndex] >> position) & 1, >+ , 0 //(zis.extra[7][vectorIndex] >> position) & 1 >+ ); >+ } >+} >+ >+static void copy(UnconditionalFlowInfo source, UnconditionalFlowInfo target) { >+ target.definiteInits = source.definiteInits; >+ target.potentialInits = source.potentialInits; >+ boolean hasNullInfo = (source.tagBits & NULL_FLAG_MASK) != 0; >+ if (hasNullInfo) { >+ target.nullBit1 = source.nullBit1; >+ target.nullBit2 = source.nullBit2; >+ target.nullBit3 = source.nullBit3; >+ target.nullBit4 = source.nullBit4; >+// target.nullBit5 = source.nullBit5; >+// target.nullBit6 = source.nullBit6; >+ } >+ target.tagBits = source.tagBits; >+ target.maxFieldCount = source.maxFieldCount; >+ if (source.extra != null) { >+ int length; >+ target.extra = new long[extraLength][]; >+ System.arraycopy(source.extra[0], 0, >+ (target.extra[0] = new long[length = source.extra[0].length]), 0, length); >+ System.arraycopy(source.extra[1], 0, >+ (target.extra[1] = new long[length]), 0, length); >+ if (hasNullInfo) { >+ for (int j = 0; j < extraLength; j++) { >+ System.arraycopy(source.extra[j], 0, >+ (target.extra[j] = new long[length]), 0, length); >+ } >+ } >+ else { >+ for (int j = 0; j < extraLength; j++) { >+ target.extra[j] = new long[length]; >+ } >+ } >+ } >+} >+ >+public void grow(int position) { >+ int vectorIndex = ((position) / BitCacheSize) - 1; >+ int length = vectorIndex + 1, oldLength; >+ if (this.extra == null) { >+ this.extra = new long[extraLength][]; >+ for (int j = 0; j < extraLength; j++) { >+ this.extra[j] = new long[length]; >+ } >+ } else if (length > (oldLength = this.extra[2].length)) { >+ for (int j = 0; j < extraLength; j++) { >+ System.arraycopy(this.extra[j], 0, >+ this.extra[j] = new long[length], 0, oldLength); >+ } >+ } >+} >+ >+static void init(UnconditionalFlowInfo zis, long [] nullBits, int position) { >+ if (position < BitCacheSize) { >+ zis.nullBit1 = nullBits[0] << position; >+ zis.nullBit2 = nullBits[1] << position; >+ zis.nullBit3 = nullBits[2] << position; >+ zis.nullBit4 = nullBits[3] << position; >+// zis.nullBit5 = nullBits[4] << position; >+// zis.nullBit6 = nullBits[5] << position; >+ } >+ else { >+ int vectorIndex = (position / BitCacheSize) - 1, >+ length = vectorIndex + 1; >+ position %= BitCacheSize; >+ zis.extra = new long[extraLength][]; >+ zis.extra[0] = new long[length]; >+ zis.extra[1] = new long[length]; >+ for (int j = 2; j < extraLength; j++) { >+ zis.extra[j] = new long[length]; >+ zis.extra[j][vectorIndex] = nullBits[j - 2] << position; >+ } >+ } >+ if (nullBits[0] != 0 || nullBits[1] != 0 >+ || nullBits[2] != 0 || nullBits[3] != 0 >+ || nullBits[4] != 0 || nullBits[5] != 0) { >+ // cascade better than nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3] >+ // by 10%+ >+ // TODO (maxime) run stats to determine which is the better order >+ zis.tagBits |= NULL_FLAG_MASK; >+ } >+ zis.maxFieldCount = 0; >+} >+ >+static boolean testEquals(UnconditionalFlowInfo zis, UnconditionalFlowInfo other) { >+ if (zis.tagBits != other.tagBits) { >+ return false; >+ } >+ if (zis.nullBit1 != other.nullBit1 >+ || zis.nullBit2 != other.nullBit2 >+ || zis.nullBit3 != other.nullBit3 >+ || zis.nullBit4 != other.nullBit4 >+ /* || zis.nullBit5 != other.nullBit5 >+ || zis.nullBit6 != other.nullBit6 */) { >+ return false; >+ } >+ int left = zis.extra == null ? 0 : zis.extra[2].length, >+ right = other.extra == null ? 0 : other.extra[2].length, >+ both = 0, i; >+ if (left > right) { >+ both = right; >+ } >+ else { >+ both = left; >+ } >+ for (i = 0; i < both ; i++) { >+ for (int j = 2; j < extraLength; j++) { >+ if (zis.extra[j][i] != >+ other.extra[j][i]) { >+ return false; >+ } >+ } >+ } >+ for (; i < left; i++) { >+ for (int j = 2; j < extraLength; j++) { >+ if (zis.extra[j][i] != 0) { >+ return false; >+ } >+ } >+ } >+ for (; i < right; i++) { >+ for (int j = 2; j < extraLength; j++) { >+ if (other.extra[j][i] != 0) { >+ return false; >+ } >+ } >+ } >+ return true; >+} >+ >+static boolean testEquals(UnconditionalFlowInfo zis, UnconditionalFlowInfo other, >+ int position) { >+ int vectorIndex = position / BitCacheSize - 1; >+ if ((zis.tagBits & other.tagBits & NULL_FLAG_MASK) == 0) { >+ return true; >+ } >+ long mask; >+ if (vectorIndex < 0) { >+ return ((zis.nullBit1 & (mask = (1L << position))) ^ >+ (other.nullBit1 & mask)) == 0 && >+ ((zis.nullBit2 & mask) ^ >+ (other.nullBit2 & mask)) == 0 && >+ ((zis.nullBit3 & mask) ^ >+ (other.nullBit3 & mask)) == 0 && >+ ((zis.nullBit4 & mask) ^ >+ (other.nullBit4 & mask)) == 0 /* && >+ ((zis.nullBit5 & mask) ^ >+ (other.nullBit5 & mask)) == 0 && >+ ((zis.nullBit6 & mask) ^ >+ (other.nullBit6 & mask)) == 0 */; >+ } >+ else { >+ int left = zis.extra == null ? >+ 0 : >+ zis.extra[0].length; >+ int right = other.extra == null ? >+ 0 : >+ other.extra[0].length; >+ int both = left < right ? left : right; >+ if (vectorIndex < both) { >+ mask = (1L << (position % BitCacheSize)); >+ for (int j = 2; j < extraLength; j++) { >+ if (((zis.extra[j][vectorIndex] & mask) >+ ^ (other.extra[j][vectorIndex] & mask)) != 0) { >+ return false; >+ } >+ } >+ return true; >+ } >+ if (vectorIndex < left) { >+ return ((zis.extra[2][vectorIndex] | >+ zis.extra[3][vectorIndex] | >+ zis.extra[4][vectorIndex] | >+ zis.extra[5][vectorIndex] | >+ zis.extra[6][vectorIndex] | >+ zis.extra[7][vectorIndex]) & >+ (1L << (position % BitCacheSize))) == 0; >+ } >+ return ((other.extra[2][vectorIndex] | >+ other.extra[3][vectorIndex] | >+ other.extra[4][vectorIndex] | >+ other.extra[5][vectorIndex] | >+ other.extra[6][vectorIndex] | >+ other.extra[7][vectorIndex]) & >+ (1L << (position % BitCacheSize))) == 0; >+ } >+} >+ >+static String testString(UnconditionalFlowInfo zis, int position) { >+ if (zis == DEAD_END) { >+ return "FlowInfo.DEAD_END"; //$NON-NLS-1$ >+ } >+ if (position < BitCacheSize) { >+ return "{" + (zis.nullBit1 >> position) //$NON-NLS-1$ >+ + "," + (zis.nullBit2 >> position) //$NON-NLS-1$ >+ + "," + (zis.nullBit3 >> position) //$NON-NLS-1$ >+ + "," + (zis.nullBit4 >> position) //$NON-NLS-1$ >+// + "," + (zis.nullBit5 >> position) //$NON-NLS-1$ >+// + "," + (zis.nullBit6 >> position) //$NON-NLS-1$ >+ + "}"; //$NON-NLS-1$ >+ } >+ else { >+ int vectorIndex = position / BitCacheSize - 1, >+ shift = position % BitCacheSize; >+ return "{" + (zis.extra[2][vectorIndex] //$NON-NLS-1$ >+ >> shift) >+ + "," + (zis.extra[3][vectorIndex] //$NON-NLS-1$ >+ >> shift) >+ + "," + (zis.extra[4][vectorIndex] //$NON-NLS-1$ >+ >> shift) >+ + "," + (zis.extra[5][vectorIndex] //$NON-NLS-1$ >+ >> shift) >+// + "," + (zis.extra[6][vectorIndex] //$NON-NLS-1$ >+// >> shift) >+// + "," + (zis.extra[7][vectorIndex] //$NON-NLS-1$ >+// >> shift) >+ + "}"; //$NON-NLS-1$ >+ } >+} >+} >+/** >+ * A class meant to augment >+ * @link{org.eclipse.jdt.internal.compiler.flow.NullInfoRegistry} with >+ * capabilities in the test domain. It especially provides factories to build >+ * fake flow info instances for use in state transitions validation. >+ */ >+/* >+ * The reason why UnconditionalFlowInfoTestHarness and this class were >+ * separated is that NullInfoRegistry redefines part of the markAs* methods, >+ * in effect preventing a harness extending NullInfoRegistry to access >+ * UnconditionalFlowInfo implementations of the said methods. >+ */ >+class NullInfoRegistryTestHarness extends NullInfoRegistry { >+ private int testPosition; >+ >+private NullInfoRegistryTestHarness() { >+ super(FlowInfo.DEAD_END); >+} >+ >+ // Interface >+/** >+ * Return the state represented by this. >+ * @return the state represented by this >+ */ >+NullReferenceImplTests.State asState() { >+ return UnconditionalFlowInfoTestHarness.asState(this, 0); >+} >+ >+/** >+ * Return the state represented by this for a variable encoded at a given position. >+ * @param position - int the position of the considered variable >+ * @return the state represented by this for a variable encoded at a given position >+ */ >+NullReferenceImplTests.State asState(int position) { >+ return UnconditionalFlowInfoTestHarness.asState(this, position); >+} >+ >+public FlowInfo copy() { >+ NullInfoRegistryTestHarness copy = >+ new NullInfoRegistryTestHarness(); >+ copy.testPosition = this.testPosition; >+ UnconditionalFlowInfoTestHarness.copy(this, copy); >+ return copy; >+} >+ >+/** >+ * Return a fake null info registry derived from an unconditional flow >+ * info. >+ * @param upstream - UnconditionalFlowInfoTestHarness the upstream flow info >+ * @return a fake null info registry derived from upstream >+ */ >+public static NullInfoRegistryTestHarness testNullInfoRegistry( >+ UnconditionalFlowInfoTestHarness upstream) { >+ NullInfoRegistry nullInfoRegistry = new NullInfoRegistry(upstream); >+ NullInfoRegistryTestHarness result = >+ new NullInfoRegistryTestHarness(); >+ result.testPosition = upstream.testPosition; >+ if (result.testPosition < BitCacheSize) { >+ result.nullBit1 = nullInfoRegistry.nullBit1; >+ result.nullBit2 = nullInfoRegistry.nullBit2; >+ result.nullBit3 = nullInfoRegistry.nullBit3; >+ result.nullBit4 = nullInfoRegistry.nullBit4; >+// result.nullBit5 = nullInfoRegistry.nullBit5; >+// result.nullBit6 = nullInfoRegistry.nullBit6; >+ } >+ else if ((nullInfoRegistry.tagBits & NULL_FLAG_MASK) != 0){ >+ int vectorIndex = (result.testPosition / BitCacheSize) - 1, >+ length = vectorIndex + 1; >+ result.extra = new long[extraLength][]; >+ result.extra[0] = new long[length]; >+ result.extra[1] = new long[length]; >+ for (int j = 2; j < extraLength; j++) { >+ result.extra[j] = new long[length]; >+ result.extra[j][vectorIndex] = nullInfoRegistry.extra[j][vectorIndex]; >+ } >+ } >+ if ((nullInfoRegistry.tagBits & NULL_FLAG_MASK) != 0) { >+ result.tagBits |= NULL_FLAG_MASK; >+ } >+ result.maxFieldCount = 0; >+ return result; >+} >+ >+/** >+ * Return true iff this flow info can be considered as equal to the one passed >+ * in parameter. >+ * @param other the flow info to compare to >+ * @return true iff this flow info compares equal to other >+ */ >+public boolean testEquals(UnconditionalFlowInfo other) { >+ return UnconditionalFlowInfoTestHarness.testEquals(this, other); >+} >+ >+/** >+ * Return true iff this flow info can be considered as equal to the one passed >+ * in parameter in respect with a single local variable which id would be >+ * position in a class with no field. >+ * @param other the flow info to compare to >+ * @param position the position of the local to consider >+ * @return true iff this flow info compares equal to other for a given local >+ */ >+public boolean testEquals(UnconditionalFlowInfo other, int position) { >+ return UnconditionalFlowInfoTestHarness.testEquals(this, other, position); >+} >+ >+/** >+ * Return a string suitable for use as a representation of this flow info >+ * within test series. >+ * @return a string suitable for use as a representation of this flow info >+ */ >+public String testString() { >+ if (this == DEAD_END) { >+ return "FlowInfo.DEAD_END"; //$NON-NLS-1$ >+ } >+ return UnconditionalFlowInfoTestHarness.testString(this, this.testPosition); >+} >+ >+/** >+ * Return a string suitable for use as a representation of this flow info >+ * within test series. >+ * @param position a position to consider instead of this flow info default >+ * test position >+ * @return a string suitable for use as a representation of this flow info >+ */ >+public String testString(int position) { >+ return UnconditionalFlowInfoTestHarness.testString(this, position); >+} >+} >+ >+interface CodeAnalysis { >+ public static final String >+ definitionStartMarker = "DEFINITION START", >+ definitionEndMarker = "DEFINITION END", >+ initializerStartMarker = "INITIALIZER START", >+ initializerEndMarker = "INITIALIZER END"; >+} >+class TransitiveClosureHolder { >+static class Element { >+ NullReferenceImplTests.State value; >+ boolean alreadyKnown; >+ Element(NullReferenceImplTests.State value) { >+ if (value == null) { >+ throw new IllegalArgumentException("not a valid element"); >+ } >+ this.value = value; >+ } >+} >+Map elements = new TreeMap(); >+public TransitiveClosureHolder() { >+ Element start = new Element(NullReferenceImplTests.State.start); >+ this.elements.put(start.value, start); >+} >+void add(NullReferenceImplTests.State value) { >+ if (value == null) { >+ throw new IllegalArgumentException("not a valid state"); >+ } >+ if (! this.elements.containsKey(value)) { >+ this.elements.put(value, new Element(value)); >+ } >+} >+void add(NullReferenceImplTests.State[] values) { >+ if (values == null) { >+ throw new IllegalArgumentException("not a valid states set"); >+ } >+ for (int i = 0, length = values.length; i < length; i++) { >+ add(values[i]); >+ } >+} >+NullReferenceImplTests.State[] asArray() { >+ int length; >+ NullReferenceImplTests.State[] result = new NullReferenceImplTests.State[length = this.elements.size()]; >+ Iterator elementsIterator = this.elements.keySet().iterator(); >+ for (int j = 0; j < length; j++) { >+ result[j] = (NullReferenceImplTests.State) elementsIterator.next(); >+ } >+ return result; >+} >+NullReferenceImplTests.State[] notAlreadyKnowns() { >+ List resultAccumulator = new ArrayList(this.elements.size()); >+ Iterator i = this.elements.values().iterator(); >+ Element current; >+ while (i.hasNext()) { >+ if (! (current = (Element) i.next()).alreadyKnown) { >+ resultAccumulator.add(current.value); >+ } >+ } >+ int length; >+ NullReferenceImplTests.State[] result = new NullReferenceImplTests.State[length = resultAccumulator.size()]; >+ for (int j = 0; j < length; j++) { >+ result[j] = (NullReferenceImplTests.State) resultAccumulator.get(j); >+ } >+ return result; >+} >+void markAllAsAlreadyKnown() { >+ Iterator i = this.elements.values().iterator(); >+ while (i.hasNext()) { >+ ((Element) i.next()).alreadyKnown = true; >+ } >+} >+public String toString() { >+ StringBuffer output = new StringBuffer(); >+ output.append("Transitive closure:\n"); >+ SortedMap sorted = new TreeMap(this.elements); >+ Iterator i = sorted.keySet().iterator(); >+ while (i.hasNext()) { >+ output.append(i.next().toString()); >+ output.append('\n'); >+ } >+ return output.toString(); >+} >+} >+ >+// PREMATURE segregate pure tooling into a separate project, keep tests only here >+/** >+ * The Generator class is meant to generate the tabular data needed by the >+ * flow information implementation level tests. While the tests should ensure >+ * non regression by leveraging their initialization tables only, any change >+ * into the flow information logic or encoding is due to yield considerable >+ * changes into the literal values sets of the initializers themselves. >+ * Tooling the production of those literals buys us flexibility. >+ * {@link #printHelp printHelp} for details. >+ */ >+class Generator { >+static NullReferenceImplTests.State[] computeTransitiveClosure() { >+ TransitiveClosureHolder transitiveClosure = new TransitiveClosureHolder(); >+ NullReferenceImplTests.State[] unknowns; >+ unknowns = transitiveClosure.notAlreadyKnowns(); >+ while (unknowns.length != 0) { >+ transitiveClosure.markAllAsAlreadyKnown(); >+ for (int i = 0, length = NullReferenceImplTransformations.transformations.length; i < length; i ++) { >+ transitiveClosure.add( >+ NullReferenceImplTransformations.transformations[i]. >+ computeOutputs(transitiveClosure.asArray())); >+ } >+ unknowns = transitiveClosure.notAlreadyKnowns(); >+ } >+ return transitiveClosure.asArray(); >+} >+public static void main(String[] args) { >+ if (args.length == 0) { >+ printHelp(false); >+ System.exit(1); >+ } >+ switch (args.length) { >+ case 1: >+ if (args[0].equals("--help")) { >+ printHelp(true); >+ System.exit(0); >+ } >+ else { >+ printHelp(false); >+ System.exit(1); >+ } >+ case 2: >+ if (args[0].equals("--printTruthTables")) { >+ File outputDir = new File(args[1]); >+ if (outputDir.isDirectory()) { >+ for (int i = 0, length = NullReferenceImplTransformations.transformations.length; i < length; i++) { >+ NullReferenceImplTransformations.transformations[i].printTruthTables(outputDir); >+ } >+ } >+ else { >+ // PREMATURE error handling >+ } >+ System.exit(0); >+ } >+ else { >+ printHelp(false); >+ System.exit(1); >+ } >+ case 3: >+ if (args[0].equals("--reinitializeFromComputedValues")) { >+ reinitializeFromComputedValues(args[1], args[2]); >+ System.out.println("Generator generated new file into " + args[2]); >+ System.exit(0); >+ } >+ case 5: >+ if (args[0].equals("--reinitializeFromComments")) { >+ reinitializeFromComments(args[1], args[2], args[3], args[4]); >+ System.out.println("Generator generated new files into " + args[2] >+ + " and " + args[4]); >+ System.exit(0); >+ } >+ default: >+ printHelp(false); >+ System.exit(1); >+ } >+} >+ >+private static void reinitializeFromComments( >+ String statesSource, String statesTarget, >+ String transformationsSource, String transformationsTarget) { >+ if (statesSource.equals(transformationsSource) || >+ statesTarget.equals(transformationsTarget)) { >+ throw new RuntimeException(); >+ } >+ try { >+ BufferedReader in; >+ BufferedWriter out; >+ NullReferenceImplTests.State.reinitializeFromComment( >+ in = new BufferedReader( >+ new FileReader(statesSource)), >+ out = new BufferedWriter(new FileWriter(statesTarget))); >+ in.close(); >+ out.close(); >+ File[] tempFiles = new File[2]; >+ tempFiles[0] = File.createTempFile("generator", "java"); >+ tempFiles[1] = File.createTempFile("generator", "java"); >+ NullReferenceImplTransformations.transformations[0].reinitializeFromComments( >+ in = new BufferedReader( >+ new FileReader(transformationsSource)), >+ out = new BufferedWriter(new FileWriter(tempFiles[0]))); >+ in.close(); >+ out.close(); >+ int i, length; >+ for (i = 1, length = NullReferenceImplTransformations.transformations.length - 1; i < length; i++) { >+ NullReferenceImplTransformations.transformations[i].reinitializeFromComments( >+ in = new BufferedReader( >+ new FileReader(tempFiles[(i + 1) % 2])), >+ out = new BufferedWriter(new FileWriter(tempFiles[i % 2]))); >+ in.close(); >+ out.close(); >+ } >+ NullReferenceImplTransformations.transformations[i].reinitializeFromComments( >+ in = new BufferedReader( >+ new FileReader(tempFiles[(i + 1) % 2])), >+ out = new BufferedWriter(new FileWriter(transformationsTarget))); >+ in.close(); >+ out.close(); >+ } catch (Throwable t) { >+ System.err.println("Generator error:"); >+ t.printStackTrace(System.err); >+ System.exit(2); >+ } >+} >+ >+private static void reinitializeFromComputedValues(String source, String target) { >+ for (int i = 0, length = NullReferenceImplTransformations.transformations.length; >+ i < length; i++) { >+ NullReferenceImplTransformations.transformations[i].hydrate(); >+ } >+ NullReferenceImplTests.State[] transitiveClosure = computeTransitiveClosure(); >+ try { >+ BufferedReader in; >+ BufferedWriter out; >+ File[] tempFiles = new File[2]; >+ tempFiles[0] = File.createTempFile("generator", "java"); >+ tempFiles[1] = File.createTempFile("generator", "java"); >+ NullReferenceImplTransformations.transformations[0].reinitializeFromComputedValues( >+ in = new BufferedReader( >+ new FileReader(source)), >+ out = new BufferedWriter(new FileWriter(tempFiles[0])), >+ transitiveClosure); >+ in.close(); >+ out.close(); >+ int i, length; >+ for (i = 1, length = NullReferenceImplTransformations.transformations.length - 1; i < length; i++) { >+ NullReferenceImplTransformations.transformations[i].reinitializeFromComputedValues( >+ in = new BufferedReader( >+ new FileReader(tempFiles[(i + 1) % 2])), >+ out = new BufferedWriter(new FileWriter(tempFiles[i % 2])), >+ transitiveClosure); >+ in.close(); >+ out.close(); >+ } >+ NullReferenceImplTransformations.transformations[i].reinitializeFromComputedValues( >+ in = new BufferedReader( >+ new FileReader(tempFiles[(i + 1) % 2])), >+ out = new BufferedWriter(new FileWriter(target)), >+ transitiveClosure); >+ in.close(); >+ out.close(); >+ } catch (Throwable t) { >+ System.err.println("Generator error:"); >+ t.printStackTrace(System.err); >+ System.exit(2); >+ } >+} >+ >+private static void printHelp(boolean longText) { >+ if (longText) { >+ System.out.println( >+ "Generator use cases\n" + >+ " - when a brand new logic is experimented for the transitions, the best\n" + >+ " way to go is to write explicit (inefficient) transformation code within\n" + >+ " UnconditionalFlowInfo, then generate the literal initializers from\n" + >+ " there; use the command\n" + >+ " --reinitializeFromComputedValues <source file> <target file>\n" + >+ " to this effect; in case of inconsistencies or errors, messages are\n" + >+ " printed to the error output stream and the result should be considered as non reliable;\n" + >+ " - when only a few changes are made to state names or a specific\n" + >+ " transitions, it should be possible to get the test initializers fixed\n" + >+ " before UnconditionalFlowInfo implements those changes; use the command\n" + >+ " --reinitializeFromComments <states source file> <states target file> <transformations source file> <transformations target file>\n" + >+ " to this effect;\n" + >+ " - the same command can be used when, while the semantics of the system\n" + >+ " are unchanged, the encoding is modified; it should then produce the\n" + >+ " initializers according to the new encoding, as defined by the comment\n" + >+ " for State.states, and the transformations as defined by their\n" + >+ " respective comment;\n" + >+ " - when a given encoding is retained, its optimization may leverage truth\n" + >+ " tables; use the --printTruthTables command to this effect.\n" + >+ " \n\n"); >+ printHelp(false); >+ } >+ else { >+ System.out.println( >+ "Usage:\n" + >+ "Generator --help\n" + >+ " prints a more detailed help message\n" + >+ "Generator --printTruthTables\n" + >+ " prints the truth tables of the transformations\n" + >+ "Generator --reinitializeFromComments <source file> <target file>\n" + >+ " generates into target file a copy of source file into which\n" + >+ " transformations initializers have been reset from their definitions\n" + >+ "Generator --reinitializeFromComputedValues <source file> <target file>\n" + >+ " generates into target file a copy of source file into which\n" + >+ " transformations definitions and initializers have been reset\n" + >+ " according to the behavior of the current UnconditionalFlowInfo\n" >+ ); >+ } >+} >+} >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 127570
: 39168