-
Notifications
You must be signed in to change notification settings - Fork 425
Suppresses RLC non-final field overwrite warning for safe constructor field initialization #7050
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
base: master
Are you sure you want to change the base?
Changes from 10 commits
158e737
325e983
4cb90d7
9d4d403
c524542
a9a1e84
dbd6447
29071ca
14aebc4
87b838c
8ad095b
fa2aef4
96c47f8
9a70147
4010022
4765ecf
143f3f4
b11cd19
dda12eb
d78354e
81c8cab
f3b9022
0d53a06
07617a7
c188d0f
7f4360a
7eb84c4
827e573
80d52c2
a5d1f60
786d477
5d9d51a
46687a1
679cbdf
000a833
2d9e299
d55afd1
93210dd
04d72ba
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 |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package org.checkerframework.checker.test.junit; | ||
|
|
||
| import java.io.File; | ||
| import java.util.List; | ||
| import org.checkerframework.checker.resourceleak.ResourceLeakChecker; | ||
| import org.checkerframework.framework.test.CheckerFrameworkPerDirectoryTest; | ||
| import org.junit.runners.Parameterized.Parameters; | ||
|
|
||
| /** | ||
| * Tests for validating safe suppression of resource leak warnings when a private field is | ||
| * initialized for the first time inside a constructor. | ||
| * | ||
| * <p>These tests check that the checker allows first-time constructor-based assignments (when safe) | ||
| * and continues to report reassignments or leaks in all other cases (e.g., after method calls, | ||
| * initializer blocks, etc.). | ||
| */ | ||
| public class ResourceLeakFirstInitConstructorTest extends CheckerFrameworkPerDirectoryTest { | ||
| public ResourceLeakFirstInitConstructorTest(List<File> testFiles) { | ||
| super( | ||
| testFiles, | ||
| ResourceLeakChecker.class, | ||
| "resourceleak-firstinitconstructor", | ||
| "-AwarnUnneededSuppressions", | ||
| "-encoding", | ||
| "UTF-8"); | ||
| } | ||
|
|
||
| @Parameters | ||
| public static String[] getTestDirs() { | ||
| return new String[] {"resourceleak-firstinitconstructor"}; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Test: Field is initialized in one constructor and reassigned in another via this() chaining. | ||
| // Expected: Warning in constructor and open() due to reassignments. | ||
|
|
||
| import java.io.FileInputStream; | ||
| import org.checkerframework.checker.calledmethods.qual.*; | ||
| import org.checkerframework.checker.mustcall.qual.*; | ||
|
|
||
| @InheritableMustCall({"close"}) | ||
| class ConstructorChainingLeak { | ||
| private @Owning FileInputStream s; | ||
|
|
||
| public ConstructorChainingLeak() throws Exception { | ||
| this(42); | ||
|
Contributor
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. Can you add a test like this one but where the
Member
Author
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. Added a test case for a constructor that calls super(). |
||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } | ||
|
|
||
| private ConstructorChainingLeak(int x) throws Exception { | ||
| s = new FileInputStream("test.txt"); | ||
| } | ||
|
|
||
| // :: error: (missing.creates.mustcall.for) | ||
| public void open() { | ||
| try { | ||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| @EnsuresCalledMethods(value = "this.s", methods = "close") | ||
| public void close() { | ||
| try { | ||
| s.close(); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // Test: Field is explicitly initialized to null and assigned in constructor. | ||
| // Expected: No warning in constructor, warning in open(). | ||
|
|
||
| import java.io.FileInputStream; | ||
| import org.checkerframework.checker.calledmethods.qual.*; | ||
| import org.checkerframework.checker.mustcall.qual.*; | ||
|
|
||
| @InheritableMustCall({"close"}) | ||
| class ExplicitNullInitializer { | ||
| private @Owning FileInputStream s = null; | ||
|
|
||
| public ExplicitNullInitializer() { | ||
| try { | ||
| s = new FileInputStream("test.txt"); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| // :: error: (missing.creates.mustcall.for) | ||
| public void open() { | ||
| try { | ||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| @EnsuresCalledMethods(value = "this.s", methods = "close") | ||
| public void close() { | ||
| try { | ||
| s.close(); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // Test: Field has no initializer and is first assigned in constructor. | ||
| // Expected: No warning in constructor, warning in open(). | ||
|
|
||
| import java.io.FileInputStream; | ||
| import org.checkerframework.checker.calledmethods.qual.*; | ||
| import org.checkerframework.checker.mustcall.qual.*; | ||
|
|
||
| @InheritableMustCall({"close"}) | ||
| class FirstAssignmentInConstructor { | ||
| private @Owning FileInputStream s; | ||
|
|
||
| public FirstAssignmentInConstructor() { | ||
| try { | ||
| s = new FileInputStream("test.txt"); // no warning | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| // :: error: (missing.creates.mustcall.for) | ||
| public void open() { | ||
| try { | ||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| @EnsuresCalledMethods(value = "this.s", methods = "close") | ||
| public void close() { | ||
| try { | ||
| s.close(); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // Test: Field has a non-null inline initializer and is reassigned in constructor and open(). | ||
| // Expected: Warning in constructor and in open(). | ||
|
|
||
| import java.io.FileInputStream; | ||
| import org.checkerframework.checker.calledmethods.qual.*; | ||
| import org.checkerframework.checker.mustcall.qual.*; | ||
|
|
||
| @InheritableMustCall({"close"}) | ||
| class InlineInitializerLeak { | ||
| private @Owning FileInputStream s = new FileInputStream("test.txt"); | ||
|
|
||
| public InlineInitializerLeak() throws Exception { | ||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } | ||
|
|
||
| // :: error: (missing.creates.mustcall.for) | ||
| public void open() { | ||
| try { | ||
| // :: error: (required.method.not.called) | ||
| s = new FileInputStream("test.txt"); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
|
|
||
| @EnsuresCalledMethods(value = "this.s", methods = "close") | ||
| public void close() { | ||
| try { | ||
| s.close(); | ||
| } catch (Exception e) { | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.