forked from eclipse-jdt/eclipse.jdt.core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhance resource leak analysis with additional annotation(s) (eclipse…
…-jdt#1716) fixes eclipse-jdt#1530 Main feature work: * Define @owning and @NotOwning in org.eclipse.jdt.annotation * Evaluate @owning on method (return) * Analysis of method body vis-a-vis its return type w/ or w/o @owning * New warning: returning a resource from a method lacking @owning * Read and evaluate @Owning/@NotOwning from .class files * add support for custom close method (@Owning-annotated method receiver) * include @owning fields: + tag from source & binary + in close() methods (canonical & custom): - complain on unclosed @owning fields (current class & supers) - evaluate super.close() as closing super's @owning fields - don't suggest to use t-w-r for fields + implicitly use syntactic analysis for fields to understand pattern: if (this.resource != null) this.resource.close(); * new problems for insufficient resource management: + field not @owning + class with @owning field not implementing AutoCloseable + class with @owning field does not implement close() + new irritant InsufficientResourceManagement to control severity * problem API in JavaCore * Support @NotOwning on subtypes of AutoCloseable to imply resource-free * detect unsafe redefinitions * detect custom wrapper resources from pattern of annotations * recognize first param of WrapperResource-ctor as implicitly @owning Improvement of flow analysis: * Improve analysis of t-w-r & try-finally * better separate analysis modes w/ vs w/o annotations + new problem ids: MandatoryCloseNotShown(AtExit) * more complete sync between outer-inner resources * improve analysis on return statement as last thing in a method * more complete integration of SwitchExpression * consider equivalence between different FTV for the same local + look up the block hierarchy for nearest relevant FTV Result: more errors unclosed-at-exit re resource from outer scope Implementation improvements: * unify how we handle passing an argument to an invocation * unify detection of risk + check null status of tracker binding and original local + respect/ignore UNREACHABLE per context: - riskyNullStatusAt: ignore - UnconditionalFlowInfo.isPotentially(Non)Null: respect * unify marking of nested tracking variables (in & out!) * more precise marking at various events (closed vs. passed to owned) * better connection between finally and try blocks + these are analysed in "wrong" order: finally then try + remember precise BlockScope where an FTV was created + remember contexts where an FTV was modified within a block - use this to re-use an FTV from finally for the beginning of try - however, create a fresh FTV in all other relevant re-assignments + transfer finallyInfo across re-assign for effect of close in finally * track FTV#owningState for more specific problem messages (future) * try harder to leverage last meaningful flowInfo at method end (see BlockScope.isLastInMethod() and its callers) * don't report "never closed" if indeed close occurred on some branch * avoid raw types in FTV & BlockScope Tests: * new ResourceLeakAnnotatedTest to repeat existing tests: + switch mode to annotation-based resource leak analysis + selective overrides where different results are expected + move/add new tests here + AbstractCompilerTest needs to search super class of ResourceLeakAnnotatedTests for inherited tests.
- Loading branch information
1 parent
a7a1673
commit 4989c7f
Showing
60 changed files
with
3,431 additions
and
456 deletions.
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
42 changes: 42 additions & 0 deletions
42
org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NotOwning.java
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,42 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 GK Software SE and others. | ||
* | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Stephan Herrmann - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.jdt.annotation; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* This annotation allows to specify absence of responsibility for certain objects as they are passed from one method to another. | ||
* <p>This annotation is the direct inverse of {@link Owning} and can be used in all locations, where that annotation is used. | ||
* {@code @NotOwning} can be used do specify a shared responsibility rather than the clear separation between sources | ||
* and sinks of resources given by {@link Owning}. | ||
* </p> | ||
* <p> | ||
* In particular the annotation {@code @NotOwning} makes explicit that absence of {@code @Owning} is by intention. | ||
* </p> | ||
* <p>Additionally, placing {@code @NotOwning} on a class that implements {@link AutoCloseable} specifies that instances of this | ||
* class do <em>not</em> hold any gc-resistant resources and therefore calling {@link AutoCloseable#close()} is not necessary. | ||
* </p> | ||
* | ||
* @since 2.3 | ||
*/ | ||
@Retention(RetentionPolicy.CLASS) | ||
@Documented | ||
@Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD }) | ||
public @interface NotOwning { | ||
// no details | ||
} |
82 changes: 82 additions & 0 deletions
82
org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/Owning.java
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,82 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 GK Software SE and others. | ||
* | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Stephan Herrmann - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.jdt.annotation; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* This annotation allows to specify responsibility for certain objects as they are passed from one method to another. | ||
* <p> | ||
* Based on this annotation, flow oriented analysis tools can be made more precise without the need to perform | ||
* full-system analysis, as the {@code @Owning} annotation describes a contract, consisting of two sides that can be | ||
* checked independently. | ||
* </p> | ||
* <p> | ||
* The Eclipse Compiler for Java™ (version 3.37 and greater) interprets this annotation when placed on a value of | ||
* type {@link AutoCloseable} or any subtype. This annotation is interpreted specifically in these locations: | ||
* </p> | ||
* <dl> | ||
* <dt>Method parameter ({@link ElementType#PARAMETER}):</dt> | ||
* <dd>Here {@code @Owning} denotes that the responsibility to close a resource passed into this parameter will lie with the | ||
* receiving method, on this particular flow. | ||
* </dd> | ||
* <dt>Method ({@link ElementType#METHOD}) - as a way to refer to the method return value:</dt> | ||
* <dd>Here {@code @Owning} denotes that responsibility to close a resource received from a call to this method will lie | ||
* with the receiving code. | ||
* </dd> | ||
* <dt>Field ({@link ElementType#FIELD})</dt> | ||
* <dd>This annotation marks that the lifecycle of a resource stored in the field is tied to the lifecycle of the | ||
* enclosing object. In order to allow for precise analysis in this situation, it is recommended that the enclosing | ||
* class of such a field implements {@link AutoCloseable}. In that case, it will be the responsibility of the class's | ||
* {@code close()} implementation to also close all resources stored in {@code @Owning} fields. | ||
* <dt>Method receiver (via {@link ElementType#TYPE_USE})</dt> | ||
* <dd>Annotating a method receiver (explicit {@code this} parameter) as owning signals that the method is responsible | ||
* for closing all contained resources. The method will be treated as a "custom close method".<br/> | ||
* The annotation is not evaluated in any other TYPE_USE locations. | ||
* </dl> | ||
* <p><strong>Responsibility</strong> to close a resource may <strong>initially arise</strong> from these situations:</p> | ||
* <ul> | ||
* <li>Instantiating a class that is a subtype of {@link AutoCloseable}.</li> | ||
* <li>Receiving a method argument via a parameter of type {@link AutoCloseable} (or subtype) that is marked as {@code @Owning}.</li> | ||
* <li>Receiving a result from a call to method that is marked as {@code @Owning} and returns {@link AutoCloseable} (or a subtype). | ||
* <ul><li>If the {@code @Owning} annotation is absent in this situation, the receiving method is <em>potentially responsible</em>.</li></ul> | ||
* </li> | ||
* <li>Within the {@code close()} method of a class implementing {@link AutoCloseable}, and within each "custom close method", | ||
* each resource field annotated as {@code @Owning} must be closed.</li> | ||
* </ul> | ||
* <p><strong>Responsibility</strong> to close a resource may be <strong>fulfilled</strong> by ensuring any of these measures on every possible path:</p> | ||
* <ul> | ||
* <li>Invoking {@link AutoCloseable#close()} or a "custom close method".</li> | ||
* <li>Passing the resource into a method where the receiving parameter has type {@link AutoCloseable} (or subtype) | ||
* and is marked as {@code @Owning}.</li> | ||
* <li>Returning the resource to the caller, provided that the current method is marked as {@code @Owning} and has a declared return type | ||
* of {@link AutoCloseable} (or a subtype).</li> | ||
* <li>Assigning the resource to a field annotated as {@code @Owning}. | ||
* <li>Within the {@code close()} method of a class implementing {@link AutoCloseable} and within a "custom close method" | ||
* closing the resource held by a field tagged as {@code @Owning} can happen either directly, or for inherited fields | ||
* by invoking {@code super.close()}, or the super version of a "custom close method". | ||
* </ul> | ||
* | ||
* @since 2.3 | ||
*/ | ||
@Retention(RetentionPolicy.CLASS) | ||
@Documented | ||
@Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE_USE }) | ||
public @interface Owning { | ||
// no details | ||
} |
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
Oops, something went wrong.