8000 RLC - [[checkOwningField() did not find a reason!]] · Issue #6987 · typetools/checker-framework · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

RLC - [[checkOwningField() did not find a reason!]] #6987

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

Open
iamsanjaymalakar opened this issue Mar 12, 2025 · 0 comments
Open

RLC - [[checkOwningField() did not find a reason!]] #6987

iamsanjaymalakar opened this issue Mar 12, 2025 · 0 comments

Comments

@iamsanjaymalakar
Copy link
Member

While running CF RLC with inference on the NJR benchmark, I encountered several leaks where CF reported:

[[checkOwningField() did not find a reason!]]

One specific example from the NJR benchmark project url1f1de5fc71_cooijmanstim_hobo_tgz-pJ8-hobo_TestingEnviromentJ8 produced the following leak warning:

src/hobo/TestingEnviroment.java:10: warning: (required.method.not.called) $$ 4 $$ method writeFile $$ field fileHandler $$ hobo.FileHandler $$ [[checkOwningField() did not find a reason!]] $$ ( 163, 187 ) $$ @MustCall method writeFile may not have been invoked on field fileHandler or any of its aliases.
	FileHandler fileHandler;
	            ^
  The type of object is: hobo.FileHandler.
  Reason for going out of scope: [[checkOwningField() did not find a reason!]]

Initially, I suspected this issue might be related to inconsistencies within the inference algorithm. Upon deeper analysis, I identified two clear patterns in the affected cases:

Pattern 1: Inheritance with Owning Fields

When a class inherits @MustCall obligations from its superclass and introduces an additional owning field, inference does not properly generate new inheritable @MustCall annotations for the subclass's owning field.

Example:

import java.io.*;
import org.checkerframework.checker.calledmethods.qual.*;
import org.checkerframework.checker.mustcall.qual.*;

public class NewTest extends InputStream {
  @Owning private RandomAccessFile stream;

  public NewTest(String fileName) throws FileNotFoundException {
    stream = new RandomAccessFile(new File(fileName), "r");
  }

  @EnsuresCalledMethods(
      value = {"this.stream"},
      methods = {"close"})
  public void releaseStream() throws IOException {
    stream.close();
  }

  @Override
  public int read() throws IOException {
    return stream.read();
  }
}

Pattern 2: Resources Closed Inside Constructors

Another problematic case occurs when the owning resource's required finalizer method is invoked directly within the constructor:

Example:

@InheritableMustCall({<init>})
public class TestingEnviroment {

        @Owning FileHandler fileHandler;
	
        @EnsuresCalledMethods(value = { "this.fileHandler" }, methods = { "writeFile" })
	public TestingEnviroment() {
		fileHandler = new FileHandler("src/fileOutput/test.txt");
		fileHandler.writeFile(winCounter[0]+" : "+winCounter[1]);
	}
	
	public static void main(String[] args) {
		new TestingEnviroment();
	}
}

In this scenario, the inference algorithm assigns an @InheritableMustCall({<init>}) annotation, despite the resource already having its required method (writeFile) invoked within the constructor. I think this inference is wrong in this case where the resource is released directly in the constructor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant
0