-
Notifications
You must be signed in to change notification settings - Fork 352
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
Add support for switch expressions to Resource Leak Checker #5005
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
// @below-java17-jdk-skip-test | ||
import org.checkerframework.checker.calledmethods.qual.*; | ||
import org.checkerframework.checker.mustcall.qual.*; | ||
import org.checkerframework.common.returnsreceiver.qual.*; | ||
|
||
class SwitchExpressions { | ||
|
||
@MustCall("a") class Foo { | ||
void a() {} | ||
|
||
@This Foo b() { | ||
return this; | ||
} | ||
|
||
void c(@CalledMethods("a") Foo this) {} | ||
} | ||
|
||
Foo makeFoo() { | ||
return new Foo(); | ||
} | ||
|
||
static void takeOwnership(@Owning Foo foo) { | ||
foo.a(); | ||
} | ||
|
||
/** cases where switch expressions are assigned to a variable */ | ||
void testSwitchAssigned(int i) { | ||
Foo switch1 = | ||
switch (i) { | ||
case 3 -> new Foo(); | ||
default -> makeFoo(); | ||
}; | ||
switch1.a(); | ||
|
||
// :: error: required.method.not.called | ||
Foo switch2 = | ||
switch (i) { | ||
case 3 -> new Foo(); | ||
default -> makeFoo(); | ||
}; | ||
|
||
// :: error: required.method.not.called | ||
Foo x = new Foo(); | ||
Foo switch3 = | ||
switch (i) { | ||
case 3 -> new Foo(); | ||
default -> x; | ||
}; | ||
switch3.a(); | ||
|
||
Foo y = new Foo(); | ||
Foo switch4 = | ||
switch (i) { | ||
case 3 -> y; | ||
default -> y; | ||
}; | ||
switch4.a(); | ||
|
||
takeOwnership( | ||
switch (i) { | ||
case 3 -> new Foo(); | ||
default -> makeFoo(); | ||
}); | ||
|
||
// :: error: required.method.not.called | ||
Foo x2 = new Foo(); | ||
takeOwnership( | ||
switch (i) { | ||
case 3 -> x2; | ||
default -> null; | ||
}); | ||
|
||
int j = 10; | ||
Foo switchInLoop = null; | ||
while (j > 0) { | ||
// :: error: required.method.not.called | ||
switchInLoop = | ||
switch (i) { | ||
case 3 -> null; | ||
default -> new Foo(); | ||
}; | ||
j--; | ||
} | ||
switchInLoop.a(); | ||
|
||
(switch (i) { | ||
case 3 -> new Foo(); | ||
default -> makeFoo(); | ||
}) | ||
.a(); | ||
} | ||
|
||
/** | ||
* tests where switch and cast expressions (possibly nested) may or may not be assigned to a | ||
* variable | ||
*/ | ||
void testSwitchCastUnassigned(int i) { | ||
// :: error: required.method.not.called | ||
if ((switch (i) { | ||
case 3 -> new Foo(); | ||
default -> null; | ||
}) | ||
!= null) { | ||
i = -i; | ||
} | ||
|
||
// :: error: required.method.not.called | ||
if (switch (i) { | ||
case 3 -> makeFoo(); | ||
default -> null; | ||
} | ||
!= null) { | ||
i = -i; | ||
} | ||
|
||
Foo x = new Foo(); | ||
if (switch (i) { | ||
case 3 -> x; | ||
default -> null; | ||
} | ||
!= null) { | ||
i = -i; | ||
} | ||
x.a(); | ||
|
||
// :: error: required.method.not.called | ||
if (((Foo) new Foo()) != null) { | ||
i = -i; | ||
} | ||
|
||
// double cast; no error | ||
Foo doubleCast = (Foo) ((Foo) makeFoo()); | ||
doubleCast.a(); | ||
|
||
// nesting casts and switch expressions; no error | ||
Foo deepNesting = | ||
(switch (i) { | ||
case 3 -> (switch (-i) { | ||
case -3 -> makeFoo(); | ||
default -> (Foo) makeFoo(); | ||
}); | ||
default -> ((Foo) new Foo()); | ||
}); | ||
deepNesting.a(); | ||
} | ||
|
||
@Owning | ||
Foo testSwitchReturnOk(int i) { | ||
return switch (i) { | ||
case 3 -> new Foo(); | ||
default -> makeFoo(); | ||
}; | ||
} | ||
|
||
@Owning | ||
Foo testSwitchReturnBad(int i) { | ||
// :: error: required.method.not.called | ||
Foo x = new Foo(); | ||
return switch (i) { | ||
case 3 -> x; | ||
default -> makeFoo(); | ||
}; | ||
} | ||
|
||
@MustCall("toString") static class Sub1 extends Object {} | ||
|
||
@MustCall("clone") static class Sub2 extends Object {} | ||
|
||
static void testSwitchSubtyping(int i) { | ||
// :: error: required.method.not.called | ||
Object toStringAndClone = | ||
switch (i) { | ||
case 3 -> new Sub1(); | ||
default -> new Sub2(); | ||
}; | ||
// at this point, for soundness, we should be responsible for calling both toString and clone on | ||
// obj... | ||
toStringAndClone.toString(); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
These tests are exactly the same as those in
TernaryExpressions
, but using switch expressions instead