-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce bottom store to improve dataflow analysis #167
base: master
Are you sure you want to change the base?
Changes from all commits
7e91f46
2237641
6ec3d77
0122edf
c276efa
cceadf7
81c8059
887a888
9af8f2e
0a4adad
6775dfa
68b238b
826d25a
d6ddb82
ee35b60
080ff48
d70186b
5b616d3
e83dea7
ea69c0a
2e03227
7408317
44c97a7
a6509e5
9041117
40a27ca
a131f41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,11 @@ public KeyForStore createEmptyStore(boolean sequentialSemantics) { | |
return new KeyForStore(this, sequentialSemantics); | ||
} | ||
|
||
@Override | ||
public KeyForStore createBottomStore(boolean sequentialSemantics) { | ||
return new KeyForStore(this, sequentialSemantics); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
@Override | ||
public KeyForStore createCopiedStore(KeyForStore store) { | ||
return new KeyForStore(store); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,9 +30,23 @@ public class NullnessStore extends InitializationStore<NullnessValue, NullnessSt | |
public NullnessStore( | ||
CFAbstractAnalysis<NullnessValue, NullnessStore, ?> analysis, | ||
boolean sequentialSemantics) { | ||
super(analysis, sequentialSemantics); | ||
this(analysis, sequentialSemantics, false); | ||
} | ||
|
||
/** | ||
* Constructor for NullnessStore. | ||
* | ||
* @param analysis the analysis class this store belongs to | ||
* @param sequentialSemantics should the analysis use sequential Java semantics? | ||
* @param isBottom is the store a bottom store? | ||
*/ | ||
public NullnessStore( | ||
CFAbstractAnalysis<NullnessValue, NullnessStore, ?> analysis, | ||
boolean sequentialSemantics, | ||
boolean isBottom) { | ||
super(analysis, sequentialSemantics, isBottom); | ||
isPolyNullNonNull = false; | ||
isPolyNullNull = false; | ||
this.isPolyNullNull = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why adding |
||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ public static void MinLen(int @MinLen(10) [] arg, int @MinLen(4) [] arg2) { | |
} else { | ||
arr = arg2; | ||
} | ||
// :: error: (assignment.type.incompatible) | ||
int @MinLen(10) [] res = arr; | ||
int @MinLen(4) [] res2 = arr; | ||
// :: error: (assignment.type.incompatible) | ||
|
@@ -24,10 +23,8 @@ public static void Bottom(int @BottomVal [] arg, int @MinLen(4) [] arg2) { | |
} else { | ||
arr = arg2; | ||
} | ||
// :: error: (assignment.type.incompatible) | ||
int @MinLen(10) [] res = arr; | ||
int @MinLen(4) [] res2 = arr; | ||
// :: error: (assignment.type.incompatible) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These changes make sense, but they also alter the meaning of this test. Should we write a new test case for the merging of |
||
int @BottomVal [] res3 = arr; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ String testWhile1() { | |
String ans = "x"; | ||
while (true) { | ||
if (true) { | ||
// :: error: (return.type.incompatible) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same issue here: we are removing all occurences of |
||
return ans; | ||
} | ||
if (true) { | ||
|
@@ -41,7 +40,6 @@ String testWhile3(boolean cond) { | |
OUTER: | ||
while (true) { | ||
if (true) { | ||
// :: error: (return.type.incompatible) | ||
return ans; | ||
} | ||
|
||
|
@@ -66,7 +64,6 @@ String testFor1() { | |
String ans = "x"; | ||
for (; ; ) { | ||
if (true) { | ||
// :: error: (return.type.incompatible) | ||
return ans; | ||
} | ||
if (true) { | ||
|
@@ -101,7 +98,6 @@ String testFor3(boolean cond) { | |
OUTER: | ||
for (; ; ) { | ||
if (true) { | ||
// :: error: (return.type.incompatible) | ||
return ans; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,10 +73,7 @@ public boolean equals(@Nullable Object obj9) { | |
public class ImmutableIntList4 { | ||
|
||
@Override | ||
@SuppressWarnings( | ||
"contracts.conditional.postcondition.not.satisfied" // TODO: `if` needs the | ||
// BOTH_TO_THEN treatment that ?: gets. | ||
) | ||
@SuppressWarnings("contracts.conditional.postcondition.not.satisfied") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add comment for reason for suppressWarning add another case return true in if and return false in else |
||
public boolean equals(@Nullable Object obj4) { | ||
boolean b; | ||
if (obj4 instanceof ImmutableIntList4) { | ||
|
@@ -91,10 +88,6 @@ public boolean equals(@Nullable Object obj4) { | |
public class ImmutableIntList5 { | ||
|
||
@Override | ||
@SuppressWarnings( | ||
"contracts.conditional.postcondition.not.satisfied" // TODO: Need special treatment | ||
// for true and false boolean literals (cut off dead parts of graph). | ||
) | ||
public boolean equals(@Nullable Object obj5) { | ||
return true ? obj5 instanceof ImmutableIntList5 : obj5 instanceof ImmutableIntList5; | ||
} | ||
|
@@ -103,10 +96,6 @@ public boolean equals(@Nullable Object obj5) { | |
public class ImmutableIntList6 { | ||
|
||
@Override | ||
@SuppressWarnings( | ||
"contracts.conditional.postcondition.not.satisfied" // TODO: Need special treatment | ||
// for true and false boolean literals (cut off dead parts of graph). | ||
) | ||
public boolean equals(@Nullable Object obj6) { | ||
return true ? obj6 instanceof ImmutableIntList6 : false; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
|
||
class DeadBranch { | ||
|
||
Object foo(@Nullable Object myObj, boolean x) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing out! I need to add another case using |
||
if (true) { | ||
myObj = new Object(); | ||
} | ||
return myObj; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,6 +102,9 @@ public FieldInitialValue(FieldAccess fieldDecl, V declared, @Nullable V initiali | |
/** Instance of the types utility. */ | ||
protected final Types types; | ||
|
||
/** The singleton of bottom store in dataflow analysis for a specific type system */ | ||
protected S bottomStore; | ||
|
||
/** | ||
* Create a CFAbstractAnalysis. | ||
* | ||
|
@@ -170,10 +173,32 @@ public T createTransferFunction() { | |
/** | ||
* Returns an empty store of the appropriate type. | ||
* | ||
* @param sequentialSemantics should the analysis use sequential Java semantics? | ||
* @return an empty store of the appropriate type | ||
*/ | ||
public abstract S createEmptyStore(boolean sequentialSemantics); | ||
|
||
/** | ||
* Create the unique shared instance of bottom store for the underlying type system. | ||
* | ||
* @param sequentialSemantics should the analysis use sequential Java semantics? | ||
* @return the bottom store instance of the appropriate type | ||
*/ | ||
public abstract S createBottomStore(boolean sequentialSemantics); | ||
|
||
/** | ||
* Get the singleton of the bottom store corresponding to the type. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... corresponding to the type system |
||
* | ||
* @param sequentialSemantics should the analysis use sequential Java semantics? | ||
* @return the shared instance of bottom store for the underyling type system | ||
*/ | ||
public S getBottomStore(boolean sequentialSemantics) { | ||
if (bottomStore == null) { | ||
bottomStore = createBottomStore(sequentialSemantics); | ||
} | ||
return bottomStore; | ||
} | ||
|
||
/** | ||
* Returns an identical copy of the store {@code s}. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new HashSet<>(Arrays.asList(lockHeld, guardBy)
Can we replace it with
ImmutableSet.of(...)
? Or should we store these bottom annotations instead of creating a new set each time this method is invoked?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually there is a final field
bottomAnnos
in the these store classes that represents the set of bottom annotations. That field is initialized in the constructor withAnnotatedTypeFactory.getBottomAnnotations()
.But
LockStore
is special. We can't use the real bottom annotations, so here thegetBottomValue
is overriden.