View | Details | Raw Unified | Return to bug 358903 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java (-1 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
2
 * Copyright (c) 2000, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 74-79 public static Test suite() { Link Here
74
	standardTests.add(ProgrammingProblemsTest.class);
74
	standardTests.add(ProgrammingProblemsTest.class);
75
	standardTests.add(ManifestAnalyzerTest.class);
75
	standardTests.add(ManifestAnalyzerTest.class);
76
	standardTests.add(InitializationTests.class);
76
	standardTests.add(InitializationTests.class);
77
	standardTests.add(ResourceLeakTests.class);
77
78
78
	// add all javadoc tests
79
	// add all javadoc tests
79
	for (int i=0, l=JavadocTest.ALL_CLASSES.size(); i<l; i++) {
80
	for (int i=0, l=JavadocTest.ALL_CLASSES.size(); i<l; i++) {
(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java (-2729 / +141 lines)
Lines 19-35 Link Here
19
 *******************************************************************************/
19
 *******************************************************************************/
20
package org.eclipse.jdt.core.tests.compiler.regression;
20
package org.eclipse.jdt.core.tests.compiler.regression;
21
21
22
import java.io.IOException;
23
import java.net.URL;
24
import java.util.Map;
22
import java.util.Map;
25
23
26
import org.eclipse.core.runtime.FileLocator;
27
import org.eclipse.core.runtime.Path;
28
import org.eclipse.core.runtime.Platform;
29
import org.eclipse.jdt.core.JavaCore;
30
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
31
32
import junit.framework.Test;
24
import junit.framework.Test;
25
26
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
33
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
27
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
34
28
35
static {
29
static {
Lines 3464-6220 public void test055a() { Link Here
3464
		},
3458
		},
3465
		"Done");
3459
		"Done");
3466
}
3460
}
3467
// Bug 349326 - [1.7] new warning for missing try-with-resources
3461
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053
3468
// a method uses an AutoCloseable without ever closing it.
3462
public void test057() {
3469
public void test056() {
3463
	this.runConformTest(
3470
	Map options = getCompilerOptions();
3471
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3472
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3473
	this.runNegativeTest(
3474
		new String[] {
3475
			"X.java",
3476
			"import java.io.File;\n" +
3477
			"import java.io.FileReader;\n" +
3478
			"import java.io.IOException;\n" +
3479
			"public class X {\n" +
3480
			"    void foo() throws IOException {\n" +
3481
			"        File file = new File(\"somefile\");\n" +
3482
			"        FileReader fileReader = new FileReader(file);\n" +
3483
// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler
3484
//			"        char[] in = new char[50];\n" +
3485
//			"        fileReader.read(in);\n" +
3486
			"    }\n" +
3487
			"    public static void main(String[] args) throws IOException {\n" +
3488
			"        new X().foo();\n" +
3489
			"    }\n" +
3490
			"}\n"
3491
		},
3492
		"----------\n" + 
3493
		"1. ERROR in X.java (at line 7)\n" + 
3494
		"	FileReader fileReader = new FileReader(file);\n" + 
3495
		"	           ^^^^^^^^^^\n" + 
3496
		"Resource leak: 'fileReader' is never closed\n" +
3497
		"----------\n",
3498
		null,
3499
		true,
3500
		options);
3501
}
3502
// Bug 349326 - [1.7] new warning for missing try-with-resources
3503
// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally
3504
public void test056a() {
3505
	Map options = getCompilerOptions();
3506
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3507
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3508
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3509
	this.runNegativeTest(
3510
		new String[] {
3464
		new String[] {
3511
			"X.java",
3465
			"X.java",
3512
			"import java.io.File;\n" +
3466
			"public class X implements AutoCloseable {\n" +
3513
			"import java.io.FileReader;\n" +
3467
			"	@Override\n" +
3514
			"import java.io.IOException;\n" +
3468
			"	public void close() throws Exception {\n" +
3515
			"public class X {\n" +
3469
			"		throw new Exception();\n" +
3516
			"    void foo() throws IOException {\n" +
3470
			"	}\n" +
3517
			"        File file = new File(\"somefile\");\n" +
3471
			"	public static void main(String[] args) {\n" +
3518
			"        FileReader fileReader = new FileReader(file);\n" +
3472
			"		final boolean foo;\n" +
3519
			"        char[] in = new char[50];\n" +
3473
			"		try (X a = new X(); X b = new X()) {\n" +
3520
			"        fileReader.read(in);\n" +
3474
			"			foo = true;\n" +
3521
			"		 fileReader.close();\n" +
3475
			"		} catch (final Exception exception) {\n" +
3522
			"    }\n" +
3476
			"			return;\n" +
3523
			"    public static void main(String[] args) {\n" +
3477
			"		}\n" +
3524
			"        try {\n" +
3478
			"	}\n" +
3525
			"            new X().foo();\n" +
3526
			"        } catch (IOException ioex) {\n" +
3527
			"            System.out.println(\"caught\");\n" +
3528
			"        }\n" +
3529
			"    }\n" +
3530
			"}\n"
3479
			"}\n"
3531
		},
3480
		},  "");	
3532
		"----------\n" + 
3533
		"1. ERROR in X.java (at line 7)\n" + 
3534
		"	FileReader fileReader = new FileReader(file);\n" + 
3535
		"	           ^^^^^^^^^^\n" + 
3536
		"Resource 'fileReader' should be managed by try-with-resource\n" + 
3537
		"----------\n",
3538
		null,
3539
		true,
3540
		options);
3541
}
3481
}
3542
// Bug 349326 - [1.7] new warning for missing try-with-resources
3482
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364008
3543
// a method uses an AutoCloseable and closes it properly in a finally block
3483
public void test058() {
3544
public void test056b() {
3545
	Map options = getCompilerOptions();
3546
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3547
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3548
	this.runConformTest(
3484
	this.runConformTest(
3549
		new String[] {
3485
		new String[] {
3550
			"X.java",
3486
			"X.java",
3551
			"import java.io.File;\n" +
3487
			"import java.io.ByteArrayOutputStream;\n" +
3552
			"import java.io.FileReader;\n" +
3488
			"import java.io.FileOutputStream;\n" +
3553
			"import java.io.IOException;\n" +
3489
			"import java.io.IOException;\n" +
3490
			"\n" +
3554
			"public class X {\n" +
3491
			"public class X {\n" +
3555
			"    void foo() throws IOException {\n" +
3492
			"\n" +
3556
			"        File file = new File(\"somefile\");\n" +
3493
			"  public static void main(final String[] args) throws IOException {\n" +
3557
			"        FileReader fileReader = new FileReader(file);\n" +
3494
			"    byte[] data;\n" +
3558
			"        try {\n" +
3495
			"    try (final ByteArrayOutputStream os = new ByteArrayOutputStream();\n" +
3559
			"            char[] in = new char[50];\n" +
3496
			"         final FileOutputStream out = new FileOutputStream(\"test.dat\")) {\n" +
3560
			"            fileReader.read(in);\n" +
3497
			"      data = os.toByteArray();\n" +
3561
			"        } finally {\n" +
3562
			"		     fileReader.close();\n" +
3563
			"        }\n" +
3564
			"    }\n" +
3565
			"    public static void main(String[] args) {\n" +
3566
			"        try {\n" +
3567
			"            new X().foo();\n" +
3568
			"        } catch (IOException ioex) {\n" +
3569
			"            System.out.println(\"caught\");\n" +
3570
			"        }\n" +
3571
			"    }\n" +
3498
			"    }\n" +
3499
			"  }\n" +
3572
			"}\n"
3500
			"}\n"
3573
		},
3501
		},  "");	
3574
		"caught", /*output*/
3575
		null/*classLibs*/,
3576
		true/*shouldFlush*/,
3577
		null/*vmargs*/,
3578
		options,
3579
		null/*requestor*/);
3580
}
3502
}
3581
// Bug 349326 - [1.7] new warning for missing try-with-resources
3503
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called
3582
// a method uses an AutoCloseable properly within try-with-resources.
3504
public void test059() {
3583
public void test056c() {
3584
	Map options = getCompilerOptions();
3585
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3586
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3587
	this.runConformTest(
3505
	this.runConformTest(
3588
		new String[] {
3506
		new String[] {
3589
			"X.java",
3507
			"X.java",
3590
			"import java.io.File;\n" +
3591
			"import java.io.FileReader;\n" +
3592
			"import java.io.IOException;\n" +
3508
			"import java.io.IOException;\n" +
3593
			"public class X {\n" +
3509
			"\n" +
3594
			"    void foo() throws IOException {\n" +
3510
			"public class X implements java.lang.AutoCloseable {\n" +
3595
			"        File file = new File(\"somefile\");\n" +
3511
			"  static boolean isOpen = true;\n" +
3596
			"        try (FileReader fileReader = new FileReader(file)) {\n" +
3512
			"  public static void main(final String[] args) throws IOException {\n" +
3597
			"            char[] in = new char[50];\n" +
3513
			"    foo();\n" +
3598
			"            fileReader.read(in);\n" +
3514
			"    System.out.println(isOpen);\n" +
3599
			"		 }\n" +
3515
			"  }\n" +
3600
			"    }\n" +
3516
			"  static boolean foo() {\n" +
3601
			"    public static void main(String[] args) {\n" +
3517
			"    try (final X x = new X()) {\n" +
3602
			"        try {\n" +
3518
			"      return x.num() >= 1;\n" +
3603
			"            new X().foo();\n" +
3604
			"        } catch (IOException ioex) {\n" +
3605
			"            System.out.println(\"caught\");\n" +
3606
			"        }\n" +
3607
			"    }\n" +
3519
			"    }\n" +
3520
			"  }\n" +
3521
			"  int num() { return 2; }\n" +
3522
			"  public void close() {\n" +
3523
			"    isOpen = false;\n" +
3524
			"  }\n" +
3608
			"}\n"
3525
			"}\n"
3609
		},
3526
		},  
3610
		"caught", /*output*/
3527
		"false");	
3611
		null/*classLibs*/,
3612
		true/*shouldFlush*/,
3613
		null/*vmargs*/,
3614
		options,
3615
		null/*requestor*/);
3616
}
3528
}
3617
// Bug 349326 - [1.7] new warning for missing try-with-resources
3529
3618
// a method uses two AutoCloseables (testing independent analysis)
3530
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called
3619
// - one closeable may be unclosed at a conditional return
3531
public void test060() {
3620
// - the other is only conditionally closed
3532
	this.runConformTest(
3621
public void test056d() {
3622
	Map options = getCompilerOptions();
3623
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3624
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3625
	this.runNegativeTest(
3626
		new String[] {
3533
		new String[] {
3627
			"X.java",
3534
			"X.java",
3628
			"import java.io.File;\n" +
3535
			"public class X implements AutoCloseable {\n" +
3629
			"import java.io.FileReader;\n" +
3536
			"	static int num = 10 ;\n" +
3630
			"import java.io.IOException;\n" +
3537
			"    public static void main(String [] args) throws Exception { \n" +
3631
			"public class X {\n" +
3538
			"    	System.out.println(foo(1));\n" +
3632
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3539
			"    	System.out.println(foo(2));\n" +
3633
			"        File file = new File(\"somefile\");\n" +
3540
			"    	System.out.println(foo(3));\n" +
3634
			"        char[] in = new char[50];\n" +
3635
			"        FileReader fileReader1 = new FileReader(file);\n" +
3636
			"        fileReader1.read(in);\n" +
3637
			"        FileReader fileReader2 = new FileReader(file);\n" +
3638
			"        fileReader2.read(in);\n" +
3639
			"        if (flag1) {\n" +
3640
			"            fileReader2.close();\n" +
3641
			"            return;\n" +
3642
			"        } else if (flag2) {\n" +
3643
			"            fileReader2.close();\n" +
3644
			"        }\n" +
3645
			"        fileReader1.close();\n" +
3646
			"    }\n" +
3647
			"    public static void main(String[] args) throws IOException {\n" +
3648
			"        new X().foo(false, true);\n" +
3649
			"    }\n" +
3541
			"    }\n" +
3650
			"}\n"
3542
			"	private static boolean foo(int where) throws Exception {\n" +
3651
		},
3543
			"		final boolean getOut = true;\n" +
3652
		"----------\n" + 
3544
			"    	System.out.println(\"Main\");\n" +
3653
		"1. WARNING in X.java (at line 10)\n" + 
3545
			"    	try (X x1 = new X(); X x2 = new X()) {\n" +
3654
		"	FileReader fileReader2 = new FileReader(file);\n" + 
3546
			"    		if (where == 1) {\n" +
3655
		"	           ^^^^^^^^^^^\n" + 
3547
			"    			return where == 1;\n" +
3656
		"Potential resource leak: 'fileReader2' may not be closed\n" +
3548
			"    		}\n" +
3657
		"----------\n" + 
3549
			"            System.out.println(\"Outer Try\");\n" +
3658
		"2. ERROR in X.java (at line 14)\n" + 
3550
			"            while (true) {\n" +
3659
		"	return;\n" + 
3551
			"            	try (Y y1 = new Y(); Y y2 = new Y()) { \n" +
3660
		"	^^^^^^^\n" + 
3552
			"            		if (where == 2) {\n" +
3661
		"Resource leak: 'fileReader1' is not closed at this location\n" + 
3553
			"            			return where == 2;\n" +
3662
		"----------\n",
3554
			"            		}		\n" +
3663
		null,
3555
			"            		System.out.println(\"Middle Try\");\n" +
3664
		true,
3556
			"            		try (Z z1 = new Z(); Z z2 = new Z()) {\n" +
3665
		options);
3557
			"            			System.out.println(\"Inner Try\");\n" +
3666
}
3558
			"            			if (getOut) \n" +
3667
//Bug 349326 - [1.7] new warning for missing try-with-resources
3559
			"            				return num >= 10;\n" +
3668
//a method uses two AutoCloseables (testing independent analysis)
3560
			"            			else\n" +
3669
//- one closeable may be unclosed at a conditional return
3561
			"            				break; \n" +
3670
//- the other is only conditionally closed
3562
			"            		}\n" +
3671
public void test056d_suppress() {
3563
			"            	}\n" +
3672
	Map options = getCompilerOptions();
3564
			"            }\n" +
3673
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3565
			"            System.out.println(\"Out of while\");\n" +
3674
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3675
	options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
3676
	this.runNegativeTest(
3677
		new String[] {
3678
			"X.java",
3679
			"import java.io.File;\n" +
3680
			"import java.io.FileReader;\n" +
3681
			"import java.io.IOException;\n" +
3682
			"public class X {\n" +
3683
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3684
			"        @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
3685
			"        char[] in = new char[50];\n" +
3686
			"        FileReader fileReader1 = new FileReader(file);\n" +
3687
			"        fileReader1.read(in);\n" +
3688
			"        @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" +
3689
			"        fileReader2.read(in);\n" +
3690
			"        if (flag1) {\n" +
3691
			"            fileReader2.close();\n" +
3692
			"            return; // not suppressed\n" +
3693
			"        } else if (flag2) {\n" +
3694
			"            fileReader2.close();\n" +
3695
			"        }\n" +
3566
			"        }\n" +
3696
			"        fileReader1.close();\n" +
3567
			"		return false;\n" +
3697
			"    }\n" +
3568
			"	}\n" +
3698
			"    @SuppressWarnings(\"resource\") // useful suppress\n" +
3569
			"    public X() {\n" +
3699
			"    void bar() throws IOException {\n" +
3570
			"        System.out.println(\"X::X\");\n" +
3700
			"        File file = new File(\"somefile\");\n" +
3701
			"        FileReader fileReader = new FileReader(file);\n" +
3702
			"        char[] in = new char[50];\n" +
3703
			"        fileReader.read(in);\n" +
3704
			"    }\n" +
3705
			"    public static void main(String[] args) throws IOException {\n" +
3706
			"        new X().foo(false, true);\n" +
3707
			"    }\n" +
3571
			"    }\n" +
3708
			"}\n"
3572
			"    @Override\n" +
3709
		},
3573
			"	public void close() throws Exception {\n" +
3710
		"----------\n" + 
3574
			"        System.out.println(\"X::~X\");\n" +
3711
		"1. WARNING in X.java (at line 6)\n" + 
3712
		"	@SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + 
3713
		"	                  ^^^^^^^^^^\n" + 
3714
		"Unnecessary @SuppressWarnings(\"resource\")\n" + 
3715
		"----------\n" + 
3716
		"2. ERROR in X.java (at line 14)\n" + 
3717
		"	return; // not suppressed\n" + 
3718
		"	^^^^^^^\n" + 
3719
		"Resource leak: 'fileReader1' is not closed at this location\n" + 
3720
		"----------\n",
3721
		null,
3722
		true,
3723
		options);
3724
}
3725
// Bug 349326 - [1.7] new warning for missing try-with-resources
3726
// Bug 362332 - Only report potential leak when closeable not created in the local scope
3727
// one method returns an AutoCleasble, a second method uses this object without ever closing it.
3728
public void test056e() {
3729
	Map options = getCompilerOptions();
3730
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3731
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3732
	this.runNegativeTest(
3733
		new String[] {
3734
			"X.java",
3735
			"import java.io.File;\n" +
3736
			"import java.io.FileReader;\n" +
3737
			"import java.io.IOException;\n" +
3738
			"public class X {\n" +
3739
			"    FileReader getReader(String filename) throws IOException {\n" +
3740
			"        File file = new File(\"somefile\");\n" +
3741
			"        FileReader fileReader = new FileReader(file);\n" +
3742
			"        return fileReader;\n" + 		// don't complain here, pass responsibility to caller
3743
			"    }\n" +
3575
			"    }\n" +
3744
			"    void foo() throws IOException {\n" +
3576
			"}\n" +
3745
			"        FileReader reader = getReader(\"somefile\");\n" +
3577
			"class Y implements AutoCloseable {\n" +
3746
			"        char[] in = new char[50];\n" +
3578
			"    public Y() {\n" +
3747
			"        reader.read(in);\n" +
3579
			"        System.out.println(\"Y::Y\");\n" +
3748
			"    }\n" +
3580
			"    }\n" +
3749
			"    public static void main(String[] args) throws IOException {\n" +
3581
			"    @Override\n" +
3750
			"        new X().foo();\n" +
3582
			"	public void close() throws Exception {\n" +
3583
			"        System.out.println(\"Y::~Y\");\n" +
3751
			"    }\n" +
3584
			"    }\n" +
3752
			"}\n"
3585
			"}\n" +
3753
		},
3586
			"class Z implements AutoCloseable {\n" +
3754
		"----------\n" + 
3587
			"    public Z() {\n" +
3755
		"1. ERROR in X.java (at line 11)\n" + 
3588
			"        System.out.println(\"Z::Z\");\n" +
3756
		"	FileReader reader = getReader(\"somefile\");\n" + 
3757
		"	           ^^^^^^\n" + 
3758
		"Potential resource leak: \'reader\' may not be closed\n" + 
3759
		"----------\n",
3760
		null,
3761
		true,
3762
		options);
3763
}
3764
// Bug 349326 - [1.7] new warning for missing try-with-resources
3765
// a method explicitly closes its AutoCloseable rather than using t-w-r
3766
public void test056f() {
3767
	Map options = getCompilerOptions();
3768
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3769
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3770
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3771
	this.runNegativeTest(
3772
		new String[] {
3773
			"X.java",
3774
			"import java.io.File;\n" +
3775
			"import java.io.FileReader;\n" +
3776
			"import java.io.IOException;\n" +
3777
			"public class X {\n" +
3778
			"    void foo() throws IOException {\n" +
3779
			"        File file = new File(\"somefile\");\n" +
3780
			"        FileReader fileReader = null;\n" +
3781
			"        try {\n" +
3782
			"            fileReader = new FileReader(file);\n" +
3783
			"            char[] in = new char[50];\n" +
3784
			"            fileReader.read(in);\n" +
3785
			"        } finally {\n" +
3786
			"            fileReader.close();\n" +
3787
			"        }\n" +
3788
			"    }\n" +
3589
			"    }\n" +
3789
			"    public static void main(String[] args) throws IOException {\n" +
3590
			"    @Override\n" +
3790
			"        new X().foo();\n" +
3591
			"	public void close() throws Exception {\n" +
3592
			"        System.out.println(\"Z::~Z\");\n" +
3791
			"    }\n" +
3593
			"    }\n" +
3792
			"}\n"
3594
			"}\n"
3793
		},
3595
		}, 
3794
		"----------\n" + 
3596
		"Main\n" + 
3795
		"1. ERROR in X.java (at line 7)\n" + 
3597
		"X::X\n" + 
3796
		"	FileReader fileReader = null;\n" + 
3598
		"X::X\n" + 
3797
		"	           ^^^^^^^^^^\n" + 
3599
		"X::~X\n" + 
3798
		"Resource 'fileReader' should be managed by try-with-resource\n" + 
3600
		"X::~X\n" + 
3799
		"----------\n",
3601
		"true\n" + 
3800
		null,
3602
		"Main\n" + 
3801
		true,
3603
		"X::X\n" + 
3802
		options);
3604
		"X::X\n" + 
3803
}
3605
		"Outer Try\n" + 
3804
// Bug 349326 - [1.7] new warning for missing try-with-resources
3606
		"Y::Y\n" + 
3805
// an AutoCloseable local is re-assigned
3607
		"Y::Y\n" + 
3806
public void test056g() {
3608
		"Y::~Y\n" + 
3807
	Map options = getCompilerOptions();
3609
		"Y::~Y\n" + 
3808
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3610
		"X::~X\n" + 
3809
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3611
		"X::~X\n" + 
3810
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3612
		"true\n" + 
3811
	this.runNegativeTest(
3613
		"Main\n" + 
3812
		new String[] {
3614
		"X::X\n" + 
3813
			"X.java",
3615
		"X::X\n" + 
3814
			"import java.io.File;\n" +
3616
		"Outer Try\n" + 
3815
			"import java.io.FileReader;\n" +
3617
		"Y::Y\n" + 
3816
			"import java.io.IOException;\n" +
3618
		"Y::Y\n" + 
3817
			"public class X {\n" +
3619
		"Middle Try\n" + 
3818
			"    void foo() throws IOException {\n" +
3620
		"Z::Z\n" + 
3819
			"        File file = new File(\"somefile\");\n" +
3621
		"Z::Z\n" + 
3820
			"        FileReader fileReader = new FileReader(file);\n" +
3622
		"Inner Try\n" + 
3821
			"        char[] in = new char[50];\n" +
3623
		"Z::~Z\n" + 
3822
			"        fileReader.read(in);\n" +
3624
		"Z::~Z\n" + 
3823
			"        fileReader = new FileReader(file);\n" +
3625
		"Y::~Y\n" + 
3824
			"        fileReader.read(in);\n" +
3626
		"Y::~Y\n" + 
3825
			"        fileReader.close();\n" +
3627
		"X::~X\n" + 
3826
			"        fileReader = null;\n" +
3628
		"X::~X\n" + 
3827
			"    }\n" +
3629
		"true");
3828
			"    public static void main(String[] args) throws IOException {\n" +
3829
			"        new X().foo();\n" +
3830
			"    }\n" +
3831
			"}\n"
3832
		},
3833
		"----------\n" + 
3834
		"1. ERROR in X.java (at line 10)\n" + 
3835
		"	fileReader = new FileReader(file);\n" + 
3836
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
3837
		"Resource leak: 'fileReader' is not closed at this location\n" + 
3838
		"----------\n",
3839
		null,
3840
		true,
3841
		options);
3842
}
3843
// Bug 349326 - [1.7] new warning for missing try-with-resources
3844
// an AutoCloseable local is re-assigned after null-assigned
3845
public void test056g2() {
3846
	Map options = getCompilerOptions();
3847
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3848
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3849
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3850
	this.runNegativeTest(
3851
		new String[] {
3852
			"X.java",
3853
			"import java.io.File;\n" +
3854
			"import java.io.FileReader;\n" +
3855
			"import java.io.IOException;\n" +
3856
			"public class X {\n" +
3857
			"    void foo() throws IOException {\n" +
3858
			"        File file = new File(\"somefile\");\n" +
3859
			"        FileReader fileReader = new FileReader(file);\n" +
3860
			"        char[] in = new char[50];\n" +
3861
			"        fileReader.read(in);\n" +
3862
			"        fileReader = null;\n" +
3863
			"        fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here
3864
			"        fileReader.read(in);\n" +
3865
			"        fileReader.close();\n" +
3866
			"    }\n" +
3867
			"    public static void main(String[] args) throws IOException {\n" +
3868
			"        new X().foo();\n" +
3869
			"    }\n" +
3870
			"}\n"
3871
		},
3872
		"----------\n" + 
3873
		"1. ERROR in X.java (at line 10)\n" + 
3874
		"	fileReader = null;\n" + 
3875
		"	^^^^^^^^^^^^^^^^^\n" + 
3876
		"Resource leak: 'fileReader' is not closed at this location\n" + 
3877
		"----------\n",
3878
		null,
3879
		true,
3880
		options);
3881
}
3882
// Bug 349326 - [1.7] new warning for missing try-with-resources
3883
// two AutoCloseables at different nesting levels (anonymous local type)
3884
public void test056h() {
3885
	Map options = getCompilerOptions();
3886
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3887
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3888
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3889
	this.runNegativeTest(
3890
		new String[] {
3891
			"X.java",
3892
			"import java.io.File;\n" +
3893
			"import java.io.FileReader;\n" +
3894
			"import java.io.IOException;\n" +
3895
			"public class X {\n" +
3896
			"    void foo() throws IOException {\n" +
3897
			"        final File file = new File(\"somefile\");\n" +
3898
			"        final FileReader fileReader = new FileReader(file);\n" +
3899
			"        char[] in = new char[50];\n" +
3900
			"        fileReader.read(in);\n" +
3901
			"        new Runnable() {\n public void run() {\n" +
3902
			"            try {\n" +
3903
			"                fileReader.close();\n" +
3904
			"                FileReader localReader = new FileReader(file);\n" +
3905
			"            } catch (IOException ex) { /* nop */ }\n" +
3906
			"        }}.run();\n" +
3907
			"    }\n" +
3908
			"    public static void main(String[] args) throws IOException {\n" +
3909
			"        new X().foo();\n" +
3910
			"    }\n" +
3911
			"}\n"
3912
		},
3913
		"----------\n" + 
3914
		"1. WARNING in X.java (at line 7)\n" + 
3915
		"	final FileReader fileReader = new FileReader(file);\n" + 
3916
		"	                 ^^^^^^^^^^\n" + 
3917
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3918
		"----------\n" + 
3919
		"2. ERROR in X.java (at line 14)\n" + 
3920
		"	FileReader localReader = new FileReader(file);\n" + 
3921
		"	           ^^^^^^^^^^^\n" + 
3922
		"Resource leak: 'localReader' is never closed\n" + 
3923
		"----------\n",
3924
		null,
3925
		true,
3926
		options);
3927
}
3928
// Bug 349326 - [1.7] new warning for missing try-with-resources
3929
// three AutoCloseables in different blocks of the same method
3930
public void test056i() {
3931
	Map options = getCompilerOptions();
3932
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3933
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3934
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3935
	this.runNegativeTest(
3936
		new String[] {
3937
			"X.java",
3938
			"import java.io.File;\n" +
3939
			"import java.io.FileReader;\n" +
3940
			"import java.io.IOException;\n" +
3941
			"public class X {\n" +
3942
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3943
			"        File file = new File(\"somefile\");\n" +
3944
			"        if (f1) {\n" +
3945
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3946
			"            char[] in = new char[50];\n" +
3947
			"            fileReader.read(in);\n" +
3948
			"            while (true) {\n" +
3949
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
3950
			"                 loopReader.close();" +
3951
			"                 break;\n" +
3952
			"            }\n" +
3953
			"        } else {\n" +
3954
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
3955
			"            if (f2)\n" +
3956
			"                fileReader.close();\n" +
3957
			"        }\n" +
3958
			"    }\n" +
3959
			"    public static void main(String[] args) throws IOException {\n" +
3960
			"        new X().foo(true, true);\n" +
3961
			"    }\n" +
3962
			"}\n"
3963
		},
3964
		"----------\n" + 
3965
		"1. ERROR in X.java (at line 8)\n" + 
3966
		"	FileReader fileReader = new FileReader(file); // err: not closed\n" + 
3967
		"	           ^^^^^^^^^^\n" + 
3968
		"Resource leak: 'fileReader' is never closed\n" + 
3969
		"----------\n" + 
3970
		"2. WARNING in X.java (at line 16)\n" + 
3971
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3972
		"	           ^^^^^^^^^^\n" + 
3973
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3974
		"----------\n",
3975
		null,
3976
		true,
3977
		options);
3978
}
3979
// Bug 349326 - [1.7] new warning for missing try-with-resources
3980
// three AutoCloseables in different blocks of the same method - problems ignored
3981
public void test056i_ignore() {
3982
	Map options = getCompilerOptions();
3983
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.IGNORE);
3984
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.IGNORE);
3985
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3986
	this.runConformTest(
3987
		new String[] {
3988
			"X.java",
3989
			"import java.io.File;\n" +
3990
			"import java.io.FileReader;\n" +
3991
			"import java.io.IOException;\n" +
3992
			"public class X {\n" +
3993
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3994
			"        File file = new File(\"somefile\");\n" +
3995
			"        if (f1) {\n" +
3996
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3997
			"            char[] in = new char[50];\n" +
3998
			"            fileReader.read(in);\n" +
3999
			"            while (true) {\n" +
4000
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
4001
			"                 loopReader.close();" +
4002
			"                 break;\n" +
4003
			"            }\n" +
4004
			"        } else {\n" +
4005
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
4006
			"            if (f2)\n" +
4007
			"                fileReader.close();\n" +
4008
			"        }\n" +
4009
			"    }\n" +
4010
			"}\n"
4011
		},
4012
		"",
4013
		null,
4014
		true,
4015
		null,
4016
		options,
4017
		null);
4018
}
4019
// Bug 349326 - [1.7] new warning for missing try-with-resources
4020
// three AutoCloseables in different blocks of the same method
4021
public void test056i2() {
4022
	Map options = getCompilerOptions();
4023
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4024
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4025
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4026
	this.runNegativeTest(
4027
		new String[] {
4028
			"X.java",
4029
			"import java.io.File;\n" + 
4030
			"import java.io.FileReader;\n" + 
4031
			"import java.io.IOException;\n" + 
4032
			"public class X {\n" +
4033
			"    void foo(boolean f1, boolean f2) throws IOException {\n" + 
4034
			"        File file = new File(\"somefile\");\n" + 
4035
			"        if (f1) {\n" + 
4036
			"            FileReader fileReader = new FileReader(file); // properly closed\n" + 
4037
			"            char[] in = new char[50];\n" + 
4038
			"            fileReader.read(in);\n" + 
4039
			"            while (true) {\n" + 
4040
			"                  fileReader.close();\n" + 
4041
			"                  FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + 
4042
			"                  loopReader.close();\n" + 
4043
			"                  break;\n" + 
4044
			"            }\n" + 
4045
			"        } else {\n" + 
4046
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
4047
			"            if (f2)\n" + 
4048
			"                fileReader.close();\n" + 
4049
			"        }\n" + 
4050
			"    }\n" + 
4051
			"    public static void main(String[] args) throws IOException {\n" + 
4052
			"        new X().foo(true, true);\n" + 
4053
			"    }\n" + 
4054
			"}\n"
4055
		},
4056
		"----------\n" + 
4057
		"1. ERROR in X.java (at line 18)\n" + 
4058
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
4059
		"	           ^^^^^^^^^^\n" + 
4060
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4061
		"----------\n",
4062
		null,
4063
		true,
4064
		options);
4065
}
4066
// Bug 349326 - [1.7] new warning for missing try-with-resources
4067
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
4068
public void test056j() {
4069
	Map options = getCompilerOptions();
4070
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4071
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4072
	this.runNegativeTest(
4073
		new String[] {
4074
			"X.java",
4075
			"import java.io.File;\n" +
4076
			"import java.io.FileReader;\n" +
4077
			"import java.io.IOException;\n" +
4078
			"public class X {\n" +
4079
			"    void foo() throws IOException {\n" +
4080
			"        File file = new File(\"somefile\");\n" +
4081
			"        FileReader fileReader = new FileReader(file);\n" +
4082
			"        read(fileReader);\n" +
4083
			"    }\n" +
4084
			"    void read(FileReader reader) { }\n" +
4085
			"    public static void main(String[] args) throws IOException {\n" +
4086
			"        new X().foo();\n" +
4087
			"    }\n" +
4088
			"}\n"
4089
		},
4090
		"----------\n" + 
4091
		"1. ERROR in X.java (at line 7)\n" + 
4092
		"	FileReader fileReader = new FileReader(file);\n" + 
4093
		"	           ^^^^^^^^^^\n" + 
4094
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4095
		"----------\n",
4096
		null,
4097
		true,
4098
		options);
4099
}
4100
// Bug 349326 - [1.7] new warning for missing try-with-resources
4101
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
4102
public void test056jconditional() {
4103
	Map options = getCompilerOptions();
4104
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4105
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4106
	this.runNegativeTest(
4107
		new String[] {
4108
			"X.java",
4109
			"import java.io.File;\n" +
4110
			"import java.io.FileReader;\n" +
4111
			"import java.io.IOException;\n" +
4112
			"public class X {\n" +
4113
			"    void foo(boolean b) throws IOException {\n" +
4114
			"        File file = new File(\"somefile\");\n" +
4115
			"        FileReader fileReader = new FileReader(file);\n" +
4116
			"        synchronized (b ? this : new X()) {\n" +
4117
			"            new ReadDelegator(fileReader);\n" +
4118
			"        }\n" +
4119
			"    }\n" +
4120
			"    class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" +
4121
			"    public static void main(String[] args) throws IOException {\n" +
4122
			"        new X().foo(true);\n" +
4123
			"    }\n" +
4124
			"}\n"
4125
		},
4126
		"----------\n" + 
4127
		"1. ERROR in X.java (at line 7)\n" + 
4128
		"	FileReader fileReader = new FileReader(file);\n" + 
4129
		"	           ^^^^^^^^^^\n" + 
4130
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4131
		"----------\n",
4132
		null,
4133
		true,
4134
		options);
4135
}
4136
// Bug 349326 - [1.7] new warning for missing try-with-resources
4137
// many locals, some are AutoCloseable.
4138
// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3,
4139
// doing so would create false positives.
4140
public void test056k() {
4141
	Map options = getCompilerOptions();
4142
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4143
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4144
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4145
	this.runNegativeTest(
4146
		new String[] {
4147
			"X.java",
4148
			"import java.io.File;\n" +
4149
			"import java.io.FileReader;\n" +
4150
			"import java.io.IOException;\n" +
4151
			"public class X {\n" +
4152
			"    void foo() throws IOException {\n" +
4153
			"        int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" +
4154
			"            i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" +
4155
			"            i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" +
4156
			"            i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" +
4157
			"            i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
4158
			"        File file = new File(\"somefile\");\n" +
4159
			"        FileReader ra1 = null, ra2 = null;\n" +
4160
			"        try {\n" +
4161
			"            ra1 = new FileReader(file);\n" +
4162
			"            ra2 = new FileReader(file);\n" +
4163
			"            FileReader ra3 = new FileReader(file);\n" +
4164
			"            char[] in = new char[50];\n" +
4165
			"            ra1.read(in);\n" +
4166
			"            ra2.read(in);\n" +
4167
			"            ra3.close();\n" +
4168
			"        } finally {\n" +
4169
			"            ra1.close();\n" +
4170
			"        }\n" +
4171
			"        int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits
4172
			"        FileReader rb1 = null, rb2 = null;\n" +
4173
			"        try {\n" +
4174
			"            rb1 = new FileReader(file);\n" +
4175
			"            rb2 = new FileReader(file);\n" +
4176
			"            FileReader rb3 = new FileReader(file);\n" +
4177
			"            char[] in = new char[50];\n" +
4178
			"            rb1.read(in);\n" +
4179
			"            rb2.read(in);\n" +
4180
			"            rb3.close();\n" +
4181
			"        } finally {\n" +
4182
			"            rb1.close();\n" +
4183
			"        }\n" +
4184
			"    }\n" +
4185
			"    public static void main(String[] args) throws IOException {\n" +
4186
			"        new X().foo();\n" +
4187
			"    }\n" +
4188
			"}\n"
4189
		},
4190
		"----------\n" + 
4191
		"1. ERROR in X.java (at line 12)\n" + 
4192
		"	FileReader ra1 = null, ra2 = null;\n" + 
4193
		"	           ^^^\n" + 
4194
		"Resource 'ra1' should be managed by try-with-resource\n" + 
4195
		"----------\n" + 
4196
		"2. ERROR in X.java (at line 15)\n" + 
4197
		"	ra2 = new FileReader(file);\n" + 
4198
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4199
		"Resource leak: 'ra2' is never closed\n" + 
4200
		"----------\n" + 
4201
		"3. ERROR in X.java (at line 16)\n" + 
4202
		"	FileReader ra3 = new FileReader(file);\n" + 
4203
		"	           ^^^\n" + 
4204
		"Resource 'ra3' should be managed by try-with-resource\n" +
4205
		"----------\n" + 
4206
		"4. ERROR in X.java (at line 25)\n" + 
4207
		"	FileReader rb1 = null, rb2 = null;\n" + 
4208
		"	           ^^^\n" + 
4209
		"Resource 'rb1' should be managed by try-with-resource\n" + 
4210
		"----------\n" + 
4211
		"5. ERROR in X.java (at line 28)\n" + 
4212
		"	rb2 = new FileReader(file);\n" + 
4213
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4214
		"Resource leak: 'rb2' is never closed\n" + 
4215
		"----------\n" + 
4216
		"6. ERROR in X.java (at line 29)\n" + 
4217
		"	FileReader rb3 = new FileReader(file);\n" + 
4218
		"	           ^^^\n" + 
4219
		"Resource 'rb3' should be managed by try-with-resource\n" + 
4220
		"----------\n",
4221
		null,
4222
		true,
4223
		options);
4224
}
4225
// Bug 349326 - [1.7] new warning for missing try-with-resources
4226
// various non-problems
4227
public void test056l() {
4228
	Map options = getCompilerOptions();
4229
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4230
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4231
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4232
	this.runNegativeTest(
4233
		new String[] {
4234
			"X.java",
4235
			"import java.io.File;\n" +
4236
			"import java.io.FileReader;\n" +
4237
			"import java.io.IOException;\n" +
4238
			"public class X {\n" +
4239
			"    X(FileReader r0) {}\n" + // don't complain against argument
4240
			"    FileReader getReader() { return null; }\n" +
4241
			"    void foo(FileReader r1) throws IOException {\n" +
4242
			"        FileReader fileReader = getReader();\n" +
4243
			"        if (fileReader == null)\n" +
4244
			"            return;\n" + // don't complain, resource is actually null
4245
			"        FileReader r3 = getReader();\n" +
4246
			"        if (r3 == null)\n" +
4247
			"            r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null
4248
			"        try {\n" +
4249
			"            char[] in = new char[50];\n" +
4250
			"            fileReader.read(in);\n" +
4251
			"            r1.read(in);\n" +
4252
			"        } finally {\n" +
4253
			"            fileReader.close();\n" +
4254
			"            r3.close();\n" +  // the effect of this close() call might be spoiled by exception in fileReader.close() above, but we ignore exception exits in the analysis
4255
			"        }\n" +
4256
			"    }\n" +
4257
			"    public static void main(String[] args) throws IOException {\n" +
4258
			"        FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
4259
			"        new X(r2).foo(new FileReader(new File(\"notthere\")));\n" +
4260
			"    }\n" +
4261
			"}\n"
4262
		},
4263
		"----------\n" + 
4264
		"1. ERROR in X.java (at line 8)\n" + 
4265
		"	FileReader fileReader = getReader();\n" + 
4266
		"	           ^^^^^^^^^^\n" + 
4267
		"Resource 'fileReader' should be managed by try-with-resource\n" + 
4268
		"----------\n" + 
4269
		"2. ERROR in X.java (at line 11)\n" + 
4270
		"	FileReader r3 = getReader();\n" + 
4271
		"	           ^^\n" + 
4272
		"Resource 'r3' should be managed by try-with-resource\n" +
4273
		"----------\n" + 
4274
		"3. ERROR in X.java (at line 24)\n" + 
4275
		"	FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + 
4276
		"	           ^^\n" + 
4277
		"Potential resource leak: 'r2' may not be closed\n" + 
4278
		"----------\n",
4279
		null,
4280
		true,
4281
		options);
4282
}
4283
// Bug 349326 - [1.7] new warning for missing try-with-resources
4284
// nested try with early exit
4285
public void test056m() {
4286
	Map options = getCompilerOptions();
4287
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4288
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4289
	this.runConformTest(
4290
		new String[] {
4291
			"X.java",
4292
			"import java.io.File;\n" +
4293
			"import java.io.FileReader;\n" +
4294
			"import java.io.IOException;\n" +
4295
			"public class X {\n" +
4296
			"    void foo() {\n" +
4297
			"        File file = new File(\"somefile\");" +
4298
			"        try {\n" +
4299
			"            FileReader fileReader = new FileReader(file);\n" +
4300
			"            try {\n" +
4301
			"                char[] in = new char[50];\n" +
4302
			"                if (fileReader.read(in)==0)\n" +
4303
			"                    return;\n" +
4304
			"            } finally {\n" +
4305
			"		         fileReader.close();\n" +
4306
			"            }\n" +
4307
			"        } catch (IOException e) {\n" +
4308
			"            System.out.println(\"caught\");\n" +
4309
			"        }\n" +
4310
			"    }\n" +
4311
			"    public static void main(String[] args) {\n" +
4312
			"        new X().foo();\n" +
4313
			"    }\n" +
4314
			"}\n"
4315
		},
4316
		"caught", /*output*/
4317
		null/*classLibs*/,
4318
		true/*shouldFlush*/,
4319
		null/*vmargs*/,
4320
		options,
4321
		null/*requestor*/);
4322
}
4323
// Bug 349326 - [1.7] new warning for missing try-with-resources
4324
// nested try should not interfere with earlier analysis.
4325
public void test056n() {
4326
	Map options = getCompilerOptions();
4327
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4328
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4329
	this.runConformTest(
4330
		new String[] {
4331
			"X.java",
4332
			"import java.io.File;\n" +
4333
			"import java.io.FileReader;\n" +
4334
			"import java.io.IOException;\n" +
4335
			"import java.io.FileNotFoundException;\n" +
4336
			"public class X {\n" +
4337
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4338
			"		FileReader fr1 = new FileReader(someFile);\n" + 
4339
			"		try {\n" + 
4340
			"			fr1.read(buf);\n" + 
4341
			"		} finally {\n" + 
4342
			"			fr1.close();\n" + 
4343
			"		}\n" + 
4344
			"		try {\n" + 
4345
			"			FileReader fr3 = new FileReader(someFile);\n" + 
4346
			"			try {\n" + 
4347
			"			} finally {\n" + 
4348
			"				fr3.close();\n" + 
4349
			"			}\n" + 
4350
			"		} catch (IOException e) {\n" + 
4351
			"		}\n" + 
4352
			"	 }\n" +
4353
			"    public static void main(String[] args) throws IOException {\n" +
4354
			"        try {\n" +
4355
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4356
			"        } catch (FileNotFoundException e) {\n" +
4357
			"            System.out.println(\"caught\");\n" +
4358
			"        }\n" +
4359
			"    }\n" +
4360
			"}\n"
4361
		},
4362
		"caught", /*output*/
4363
		null/*classLibs*/,
4364
		true/*shouldFlush*/,
4365
		null/*vmargs*/,
4366
		options,
4367
		null/*requestor*/);
4368
}
4369
// Bug 349326 - [1.7] new warning for missing try-with-resources
4370
// if close is guarded by null check this should still be recognized as definitely closed
4371
public void test056o() {
4372
	Map options = getCompilerOptions();
4373
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4374
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4375
	this.runConformTest(
4376
		new String[] {
4377
			"X.java",
4378
			"import java.io.File;\n" +
4379
			"import java.io.FileReader;\n" +
4380
			"import java.io.IOException;\n" +
4381
			"import java.io.FileNotFoundException;\n" +
4382
			"public class X {\n" +
4383
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4384
			"		FileReader fr1 = null;\n" + 
4385
			"		try {\n" +
4386
			"           fr1 = new FileReader(someFile);" + 
4387
			"			fr1.read(buf);\n" + 
4388
			"		} finally {\n" + 
4389
			"			if (fr1 != null)\n" +
4390
			"               try {\n" +
4391
			"                   fr1.close();\n" +
4392
			"               } catch (IOException e) { /*do nothing*/ }\n" + 
4393
			"		}\n" + 
4394
			"	 }\n" +
4395
			"    public static void main(String[] args) throws IOException {\n" +
4396
			"        try {\n" +
4397
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4398
			"        } catch (FileNotFoundException e) {\n" +
4399
			"            System.out.println(\"caught\");\n" +
4400
			"        }\n" +
4401
			"    }\n" +
4402
			"}\n"
4403
		},
4404
		"caught", /*output*/
4405
		null/*classLibs*/,
4406
		true/*shouldFlush*/,
4407
		null/*vmargs*/,
4408
		options,
4409
		null/*requestor*/);
4410
}
4411
// Bug 349326 - [1.7] new warning for missing try-with-resources
4412
// Bug 362332 - Only report potential leak when closeable not created in the local scope
4413
// a method uses an AutoCloseable without ever closing it, type from a type variable
4414
public void test056p() {
4415
	Map options = getCompilerOptions();
4416
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4417
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4418
	this.runNegativeTest(
4419
		new String[] {
4420
			"X.java",
4421
			"import java.io.File;\n" +
4422
			"import java.io.FileReader;\n" +
4423
			"import java.io.Reader;\n" +
4424
			"import java.io.IOException;\n" +
4425
			"public abstract class X <T extends Reader> {\n" +
4426
			"    void foo() throws IOException {\n" +
4427
			"        File file = new File(\"somefile\");\n" +
4428
			"        T fileReader = newReader(file);\n" +
4429
			"        char[] in = new char[50];\n" +
4430
			"        fileReader.read(in);\n" +
4431
			"    }\n" +
4432
			"    abstract T newReader(File file) throws IOException;\n" +
4433
			"    public static void main(String[] args) throws IOException {\n" +
4434
			"        new X<FileReader>() {\n" +
4435
			"            FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" +
4436
			"        }.foo();\n" +
4437
			"    }\n" +
4438
			"}\n"
4439
		},
4440
		"----------\n" + 
4441
		"1. ERROR in X.java (at line 8)\n" + 
4442
		"	T fileReader = newReader(file);\n" + 
4443
		"	  ^^^^^^^^^^\n" + 
4444
		"Potential resource leak: \'fileReader\' may not be closed\n" +
4445
		"----------\n",
4446
		null,
4447
		true,
4448
		options);
4449
}
4450
// Bug 349326 - [1.7] new warning for missing try-with-resources
4451
// closed in dead code
4452
public void test056q() {
4453
	Map options = getCompilerOptions();
4454
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4455
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4456
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4457
	this.runNegativeTest(
4458
		new String[] {
4459
			"X.java",
4460
			"import java.io.File;\n" +
4461
			"import java.io.FileReader;\n" +
4462
			"import java.io.IOException;\n" +
4463
			"public class X {\n" +
4464
			"    void foo() throws IOException {\n" +
4465
			"        File file = new File(\"somefile\");\n" +
4466
			"        FileReader fileReader = new FileReader(file);\n" +
4467
			"        char[] in = new char[50];\n" +
4468
			"        fileReader.read(in);\n" +
4469
			"        if (2*2 == 4)\n" +
4470
			"        	return;\n" +
4471
			"        fileReader.close();\n" +
4472
			"    }\n" +
4473
			"    public static void main(String[] args) throws IOException {\n" +
4474
			"        new X().foo();\n" +
4475
			"    }\n" +
4476
			"}\n"
4477
		},
4478
		"----------\n" + 
4479
		"1. ERROR in X.java (at line 7)\n" + 
4480
		"	FileReader fileReader = new FileReader(file);\n" + 
4481
		"	           ^^^^^^^^^^\n" + 
4482
		"Resource leak: 'fileReader' is never closed\n" + 
4483
		"----------\n" + 
4484
		"2. WARNING in X.java (at line 10)\n" + 
4485
		"	if (2*2 == 4)\n" + 
4486
		"	    ^^^^^^^^\n" + 
4487
		"Comparing identical expressions\n" + 
4488
		"----------\n" + 
4489
		"3. WARNING in X.java (at line 12)\n" + 
4490
		"	fileReader.close();\n" + 
4491
		"	^^^^^^^^^^^^^^^^^^\n" + 
4492
		"Dead code\n" + 
4493
		"----------\n",
4494
		null,
4495
		true,
4496
		options);
4497
}
4498
// Bug 349326 - [1.7] new warning for missing try-with-resources
4499
// properly closed, dead code in between
4500
public void test056r() {
4501
	Map options = getCompilerOptions();
4502
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4503
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4504
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4505
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4506
	this.runNegativeTest(
4507
		new String[] {
4508
			"X.java",
4509
			"import java.io.File;\n" +
4510
			"import java.io.FileReader;\n" +
4511
			"import java.io.IOException;\n" +
4512
			"public class X {\n" +
4513
			"    void foo() throws IOException {\n" +
4514
			"        File file = new File(\"somefile\");\n" +
4515
			"        FileReader fr = new FileReader(file);\n" +
4516
			"  		 Object b = null;\n" + 
4517
			"        fr.close();\n" + 
4518
			"        if (b != null) {\n" + 
4519
			"            fr = new FileReader(file);\n" + 
4520
			"            return;\n" + 
4521
			"        } else {\n" + 
4522
			"            System.out.print(42);\n" + 
4523
			"        }\n" + 
4524
			"        return;     // Should not complain about fr\n" +
4525
			"    }\n" +
4526
			"    public static void main(String[] args) throws IOException {\n" +
4527
			"        new X().foo();\n" +
4528
			"    }\n" +
4529
			"}\n"
4530
		},
4531
		"----------\n" + 
4532
		"1. ERROR in X.java (at line 10)\n" + 
4533
		"	if (b != null) {\n" + 
4534
		"            fr = new FileReader(file);\n" + 
4535
		"            return;\n" + 
4536
		"        } else {\n" + 
4537
		"	               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4538
		"Dead code\n" + 
4539
		"----------\n" + 
4540
		"2. WARNING in X.java (at line 13)\n" + 
4541
		"	} else {\n" + 
4542
		"            System.out.print(42);\n" + 
4543
		"        }\n" + 
4544
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4545
		"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + 
4546
		"----------\n",
4547
		null,
4548
		true,
4549
		options);
4550
}
4551
// Bug 349326 - [1.7] new warning for missing try-with-resources
4552
// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation
4553
public void test056s() {
4554
	Map options = getCompilerOptions();
4555
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4556
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4557
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4558
	this.runNegativeTest(
4559
		new String[] {
4560
			"X.java",
4561
			"import java.io.File;\n" + 
4562
			"import java.io.FileReader;\n" + 
4563
			"import java.io.IOException;\n" + 
4564
			"public class X {\n" + 
4565
			"    void foo() throws IOException {\n" + 
4566
			"        File file = new File(\"somefile\");\n" + 
4567
			"        try (FileReader fileReader = new FileReader(file);) {\n" + 
4568
			"            char[] in = new char[50];\n" + 
4569
			"            fileReader.read(in);\n" + 
4570
			"            fileReader = new FileReader(file);  // debug here\n" + 
4571
			"            fileReader.read(in);\n" + 
4572
			"        }\n" + 
4573
			"    }\n" +
4574
			"    public static void main(String[] args) throws IOException {\n" + 
4575
			"        new X().foo();\n" + 
4576
			"    }\n" + 
4577
			"}\n"
4578
		},
4579
		"----------\n" + 
4580
		"1. ERROR in X.java (at line 10)\n" + 
4581
		"	fileReader = new FileReader(file);  // debug here\n" + 
4582
		"	^^^^^^^^^^\n" + 
4583
		"The resource fileReader of a try-with-resources statement cannot be assigned\n" + 
4584
		"----------\n",
4585
		null,
4586
		true,
4587
		options);
4588
}
4589
// Bug 349326 - [1.7] new warning for missing try-with-resources
4590
// resource is closed, dead code follows
4591
public void test056t() {
4592
	Map options = getCompilerOptions();
4593
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4594
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4595
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4596
	this.runNegativeTest(
4597
		new String[] {
4598
			"X.java",
4599
			"import java.io.FileReader;\n" + 
4600
			"import java.io.IOException;\n" + 
4601
			"public class X {\n" + 
4602
			"    void foo31() throws IOException {\n" + 
4603
			"        FileReader reader = new FileReader(\"file\"); //warning\n" +
4604
			"        if (reader != null) {\n" + 
4605
			"            reader.close();\n" + 
4606
			"        } else {\n" + 
4607
			"            // nop\n" + 
4608
			"        }\n" + 
4609
			"    }\n" + 
4610
			"    public static void main(String[] args) throws IOException {\n" + 
4611
			"        new X().foo31();\n" + 
4612
			"    }\n" + 
4613
			"}\n"
4614
		},
4615
		"----------\n" + 
4616
		"1. ERROR in X.java (at line 8)\n" + 
4617
		"	} else {\n" + 
4618
		"            // nop\n" + 
4619
		"        }\n" + 
4620
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4621
		"Dead code\n" + 
4622
		"----------\n",
4623
		null,
4624
		true,
4625
		options);
4626
}
4627
// Bug 349326 - [1.7] new warning for missing try-with-resources
4628
// resource is reassigned within t-w-r with different resource
4629
// was initially broken due to https://bugs.eclipse.org/358827
4630
public void test056u() {
4631
	Map options = getCompilerOptions();
4632
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4633
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4634
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4635
	this.runNegativeTest(
4636
		new String[] {
4637
			"X.java",
4638
			"import java.io.FileReader;\n" +
4639
			"public class X {\n" +
4640
			"    void foo() throws Exception {\n" +
4641
			"        FileReader reader1 = new FileReader(\"file1\");\n" +
4642
			"        FileReader reader2 = new FileReader(\"file2\");\n" +
4643
			"        reader2 = reader1;// this disconnects reader 2\n" +
4644
			"        try (FileReader reader3 = new FileReader(\"file3\")) {\n" +
4645
			"            int ch;\n" +
4646
			"            while ((ch = reader2.read()) != -1) {\n" +
4647
			"                System.out.println(ch);\n" +
4648
			"                reader1.read();\n" +
4649
			"            }\n" +
4650
			"            reader2 = reader1; // warning 1 regarding original reader1\n" + // this warning was missing
4651
			"            reader2 = reader1; // warning 2 regarding original reader1\n" +
4652
			"        } finally {\n" +
4653
			"            if (reader2 != null) {\n" +
4654
			"                reader2.close();\n" +
4655
			"            } else {\n" +
4656
			"                System.out.println();\n" +
4657
			"            }\n" +
4658
			"        }\n" +
4659
			"    }\n" +
4660
			"}\n"
4661
		},
4662
		"----------\n" + 
4663
		"1. ERROR in X.java (at line 5)\n" + 
4664
		"	FileReader reader2 = new FileReader(\"file2\");\n" + 
4665
		"	           ^^^^^^^\n" + 
4666
		"Resource leak: 'reader2' is never closed\n" + 
4667
		"----------\n" + 
4668
		"2. ERROR in X.java (at line 13)\n" + 
4669
		"	reader2 = reader1; // warning 1 regarding original reader1\n" + 
4670
		"	^^^^^^^^^^^^^^^^^\n" + 
4671
		"Resource leak: 'reader1' is not closed at this location\n" + 
4672
		"----------\n" + 
4673
		"3. ERROR in X.java (at line 14)\n" + 
4674
		"	reader2 = reader1; // warning 2 regarding original reader1\n" + 
4675
		"	^^^^^^^^^^^^^^^^^\n" + 
4676
		"Resource leak: 'reader1' is not closed at this location\n" + 
4677
		"----------\n",
4678
		null,
4679
		true,
4680
		options);
4681
}
4682
// Bug 349326 - [1.7] new warning for missing try-with-resources
4683
// scope-related pbs reported in https://bugs.eclipse.org/349326#c70 and https://bugs.eclipse.org/349326#c82  
4684
public void test056v() {
4685
	Map options = getCompilerOptions();
4686
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4687
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4688
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.WARNING);
4689
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4690
	this.runNegativeTest(
4691
		new String[] {
4692
			"X.java",
4693
			"import java.io.FileReader;\n" + 
4694
			"public class X {\n" + 
4695
			"    boolean foo1() throws Exception {\n" + 
4696
			"        FileReader reader = new FileReader(\"file\");\n" + 
4697
			"        try {\n" + 
4698
			"            int ch;\n" + 
4699
			"            while ((ch = reader.read()) != -1) {\n" + 
4700
			"                System.out.println(ch);\n" + 
4701
			"                reader.read();\n" + 
4702
			"            }\n" + 
4703
			"            if (ch > 10) {\n" + 
4704
			"                return true;\n" + 
4705
			"            }\n" + 
4706
			"            return false;\n" + // return while resource from enclosing scope remains unclosed
4707
			"        } finally {\n" + 
4708
			"        }\n" + 
4709
			"    }\n" + 
4710
			"    void foo111() throws Exception {\n" + 
4711
			"        FileReader reader111 = new FileReader(\"file2\");\n" + 
4712
			"        try {\n" + 
4713
			"            int ch;\n" + 
4714
			"            while ((ch = reader111.read()) != -1) {\n" + 
4715
			"                System.out.println(ch);\n" + 
4716
			"                reader111.read();\n" + 
4717
			"            }\n" + 
4718
			"            return;\n" + // this shouldn't spoil the warning "should be managed with t-w-r" 
4719
			"        } finally {\n" + 
4720
			"            if (reader111 != null) {\n" + 
4721
			"                reader111.close();\n" + 
4722
			"            }\n" + 
4723
			"        }\n" + 
4724
			"    }\n" +
4725
			"    void foo2() throws Exception {\n" + 
4726
			"        FileReader reader2 = new FileReader(\"file\");\n" + 
4727
			"        try {\n" + 
4728
			"            int ch;\n" + 
4729
			"            while ((ch = reader2.read()) != -1) {\n" + 
4730
			"                System.out.println(ch);\n" + 
4731
			"                reader2.read();\n" + 
4732
			"            }\n" + 
4733
			"            if (ch > 10) {\n" + 
4734
			"                return;\n" + // potential leak
4735
			"            }\n" + 
4736
			"        } finally {\n" + 
4737
			"        }\n" +
4738
			"        reader2.close();\n" + // due to this close we don't say "never closed"
4739
			"    }\n" + 
4740
			"}\n"
4741
		},
4742
		"----------\n" + 
4743
		"1. ERROR in X.java (at line 4)\n" + 
4744
		"	FileReader reader = new FileReader(\"file\");\n" + 
4745
		"	           ^^^^^^\n" + 
4746
		"Resource leak: 'reader' is never closed\n" + 
4747
		"----------\n" + 
4748
		"2. WARNING in X.java (at line 19)\n" + 
4749
		"	FileReader reader111 = new FileReader(\"file2\");\n" + 
4750
		"	           ^^^^^^^^^\n" + 
4751
		"Resource 'reader111' should be managed by try-with-resource\n" + 
4752
		"----------\n" + 
4753
		"3. ERROR in X.java (at line 42)\n" + 
4754
		"	return;\n" + 
4755
		"	^^^^^^^\n" + 
4756
		"Resource leak: 'reader2' is not closed at this location\n" + 
4757
		"----------\n",
4758
		null,
4759
		true,
4760
		options);
4761
}
4762
// Bug 349326 - [1.7] new warning for missing try-with-resources
4763
// end of method is dead end, but before we have both a close() and an early return
4764
public void test056w() {
4765
	Map options = getCompilerOptions();
4766
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4767
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4768
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4769
	this.runNegativeTest(
4770
		new String[] {
4771
			"X.java",
4772
			"import java.io.FileReader;\n" + 
4773
			"public class X {\n" + 
4774
			"    boolean foo1() throws Exception {\n" + 
4775
			"        FileReader reader = new FileReader(\"file\");\n" + 
4776
			"        try {\n" + 
4777
			"            int ch;\n" + 
4778
			"            while ((ch = reader.read()) != -1) {\n" + 
4779
			"                System.out.println(ch);\n" + 
4780
			"                reader.read();\n" + 
4781
			"            }\n" + 
4782
			"            if (ch > 10) {\n" +
4783
			"				 reader.close();\n" + 
4784
			"                return true;\n" + 
4785
			"            }\n" + 
4786
			"            return false;\n" + 
4787
			"        } finally {\n" + 
4788
			"        }\n" + 
4789
			"    }\n" + 
4790
			"}\n"
4791
		},
4792
		"----------\n" + 
4793
		"1. ERROR in X.java (at line 15)\n" + 
4794
		"	return false;\n" + 
4795
		"	^^^^^^^^^^^^^\n" + 
4796
		"Resource leak: 'reader' is not closed at this location\n" + 
4797
		"----------\n",
4798
		null,
4799
		true,
4800
		options);
4801
}
4802
// Bug 349326 - [1.7] new warning for missing try-with-resources
4803
// different early exits, if no close seen report as definitely unclosed
4804
public void test056x() {
4805
	Map options = getCompilerOptions();
4806
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4807
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4808
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4809
	this.runNegativeTest(
4810
		new String[] {
4811
			"X.java",
4812
			"import java.io.FileReader;\n" +
4813
			"public class X {\n" +
4814
			"    void foo31(boolean b) throws Exception {\n" +
4815
			"        FileReader reader = new FileReader(\"file\");\n" +
4816
			"        if (b) {\n" +
4817
			"            reader.close();\n" +
4818
			"        } else {\n" +
4819
			"            return; // warning\n" +
4820
			"        }\n" +
4821
			"    }\n" +
4822
			"    void foo32(boolean b) throws Exception {\n" +
4823
			"        FileReader reader = new FileReader(\"file\"); // warn here\n" +
4824
			"        return;\n" +
4825
			"    }\n" +
4826
			"}\n"
4827
		},
4828
		"----------\n" +
4829
		"1. ERROR in X.java (at line 8)\n" +
4830
		"	return; // warning\n" +
4831
		"	^^^^^^^\n" +
4832
		"Resource leak: 'reader' is not closed at this location\n" +
4833
		"----------\n" +
4834
		"2. ERROR in X.java (at line 12)\n" +
4835
		"	FileReader reader = new FileReader(\"file\"); // warn here\n" +
4836
		"	           ^^^^^^\n" +
4837
		"Resource leak: 'reader' is never closed\n" +
4838
		"----------\n",
4839
		null,
4840
		true,
4841
		options);
4842
}
4843
// Bug 349326 - [1.7] new warning for missing try-with-resources
4844
// nested method passes the resource to outside code
4845
public void test056y() {
4846
	Map options = getCompilerOptions();
4847
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4848
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4849
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4850
	this.runNegativeTest(
4851
		new String[] {
4852
			"X.java",
4853
			"import java.io.FileReader;\n" +
4854
			"public class X {\n" +
4855
			"    void foo31(boolean b) throws Exception {\n" +
4856
			"        final FileReader reader31 = new FileReader(\"file\");\n" +
4857
			"        new Runnable() {\n" +
4858
			"            public void run() {\n" +
4859
			"                foo18(reader31);\n" +
4860
			"            }\n" +
4861
			"        }.run();\n" +
4862
			"    }\n" +
4863
			"    void foo18(FileReader r18) {\n" +
4864
			"        // could theoretically close r18;\n" +
4865
			"    }\n" +
4866
			"    abstract class ResourceProvider {\n" +
4867
			"        abstract FileReader provide();" +
4868
			"    }\n" +
4869
			"    ResourceProvider provider;" +
4870
			"    void foo23() throws Exception {\n" +
4871
			"        final FileReader reader23 = new FileReader(\"file\");\n" +
4872
			"        provider = new ResourceProvider() {\n" +
4873
			"            public FileReader provide() {\n" +
4874
			"                return reader23;\n" +
4875
			"            }\n" +
4876
			"        };\n" +
4877
			"    }\n" +
4878
			"}\n"
4879
		},
4880
		"----------\n" + 
4881
		"1. WARNING in X.java (at line 4)\n" + 
4882
		"	final FileReader reader31 = new FileReader(\"file\");\n" + 
4883
		"	                 ^^^^^^^^\n" + 
4884
		"Potential resource leak: 'reader31' may not be closed\n" + 
4885
		"----------\n" + 
4886
		"2. WARNING in X.java (at line 17)\n" + 
4887
		"	final FileReader reader23 = new FileReader(\"file\");\n" + 
4888
		"	                 ^^^^^^^^\n" + 
4889
		"Potential resource leak: 'reader23' may not be closed\n" + 
4890
		"----------\n",
4891
		null,
4892
		true,
4893
		options);
4894
}
4895
// Bug 349326 - [1.7] new warning for missing try-with-resources
4896
// resource assigned to second local and is (potentially) closed on the latter
4897
public void test056z() {
4898
	Map options = getCompilerOptions();
4899
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4900
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4901
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4902
	this.runNegativeTest(
4903
		new String[] {
4904
			"X.java",
4905
			"import java.io.FileReader;\n" +
4906
			"public class X {\n" +
4907
			"    void foo17() throws Exception {\n" +
4908
			"        FileReader reader17 = new FileReader(\"file\");\n" +
4909
			"        final FileReader readerCopy = reader17;\n" +
4910
			"        readerCopy.close();\n" +
4911
			"    }\n" +
4912
			"    void foo17a() throws Exception {\n" +
4913
			"        FileReader reader17a = new FileReader(\"file\");\n" +
4914
			"        FileReader readerCopya;" +
4915
			"		 readerCopya = reader17a;\n" +
4916
			"        bar(readerCopya);\n" + // potentially closes
4917
			"    }\n" +
4918
			"    void bar(FileReader r) {}\n" +
4919
			"}\n"
4920
		},
4921
		"----------\n" + 
4922
		"1. ERROR in X.java (at line 9)\n" + 
4923
		"	FileReader reader17a = new FileReader(\"file\");\n" + 
4924
		"	           ^^^^^^^^^\n" + 
4925
		"Potential resource leak: 'reader17a' may not be closed\n" + 
4926
		"----------\n",
4927
		null,
4928
		true,
4929
		options);
4930
}
4931
// Bug 349326 - [1.7] new warning for missing try-with-resources
4932
// multiple early exists from nested scopes (always closed) 
4933
public void test056zz() {
4934
	Map options = getCompilerOptions();
4935
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4936
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4937
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
4938
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4939
	this.runNegativeTest(
4940
		new String[] {
4941
			"X.java",
4942
			"import java.io.FileReader;\n" +
4943
			"public class X {\n" +
4944
			"    void foo16() throws Exception {\n" +
4945
			"        FileReader reader16 = new FileReader(\"file\");\n" +
4946
			"        try {\n" +
4947
			"            reader16.close();\n " +
4948
			"            return;\n" +
4949
			"        } catch (RuntimeException re) {\n" +
4950
			"            return;\n" +
4951
			"        } catch (Error e) {\n" +
4952
			"            return;\n" +
4953
			"        } finally {\n" +
4954
			"            reader16.close();\n " +
4955
			"        }\n" +
4956
			"    }\n" +
4957
			"}\n"
4958
		},
4959
		"----------\n" + 
4960
		"1. ERROR in X.java (at line 4)\n" + 
4961
		"	FileReader reader16 = new FileReader(\"file\");\n" + 
4962
		"	           ^^^^^^^^\n" + 
4963
		"Resource 'reader16' should be managed by try-with-resource\n" + 
4964
		"----------\n",
4965
		null,
4966
		true,
4967
		options);
4968
}
4969
// Bug 349326 - [1.7] new warning for missing try-with-resources
4970
// multiple early exists from nested scopes (never closed) 
4971
public void test056zzz() {
4972
	Map options = getCompilerOptions();
4973
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4974
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4975
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
4976
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4977
	this.runNegativeTest(
4978
		new String[] {
4979
			"X.java",
4980
			"import java.io.FileReader;\n" +
4981
			"public class X {\n" +
4982
			"    void foo16() throws Exception {\n" +
4983
			"        FileReader reader16 = new FileReader(\"file\");\n" +
4984
			"        try {\n" +
4985
			"            return;\n" +
4986
			"        } catch (RuntimeException re) {\n" +
4987
			"            return;\n" +
4988
			"        } catch (Error e) {\n" +
4989
			"            return;\n" +
4990
			"        } finally {\n" +
4991
			"            System.out.println();\n " +
4992
			"        }\n" +
4993
			"    }\n" +
4994
			"}\n"
4995
		},
4996
		"----------\n" + 
4997
		"1. ERROR in X.java (at line 4)\n" + 
4998
		"	FileReader reader16 = new FileReader(\"file\");\n" + 
4999
		"	           ^^^^^^^^\n" + 
5000
		"Resource leak: 'reader16' is never closed\n" + 
5001
		"----------\n",
5002
		null,
5003
		true,
5004
		options);
5005
}
5006
// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
5007
// explicit throw is a true method exit here
5008
public void test056throw1() {
5009
	Map options = getCompilerOptions();
5010
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5011
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5012
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
5013
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
5014
	this.runNegativeTest(
5015
		new String[] {
5016
			"X.java",
5017
			"import java.io.FileReader;\n" +
5018
			"public class X {\n" +
5019
			"    void foo2(boolean a, boolean b, boolean c) throws Exception {\n" +
5020
			"        FileReader reader = new FileReader(\"file\");\n" +
5021
			"        if(a)\n" +
5022
			"            throw new Exception();    //warning 1\n" +
5023
			"        else if (b)\n" +
5024
			"            reader.close();\n" +
5025
			"        else if(c)\n" +
5026
			"            throw new Exception();    //warning 2\n" +
5027
			"        reader.close();\n" +
5028
			"    }\n" +
5029
			"}\n"
5030
		},
5031
		"----------\n" + 
5032
		"1. ERROR in X.java (at line 6)\n" +
5033
		"	throw new Exception();    //warning 1\n" +
5034
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5035
		"Resource leak: 'reader' is not closed at this location\n" +
5036
		"----------\n" +
5037
		"2. ERROR in X.java (at line 10)\n" +
5038
		"	throw new Exception();    //warning 2\n" +
5039
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5040
		"Resource leak: 'reader' is not closed at this location\n" +
5041
		"----------\n",
5042
		null,
5043
		true,
5044
		options);	
5045
}
5046
// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
5047
// close() within finally provides protection for throw
5048
public void test056throw2() {
5049
	Map options = getCompilerOptions();
5050
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5051
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5052
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
5053
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
5054
	this.runNegativeTest(
5055
		new String[] {
5056
			"X.java",
5057
			"import java.io.FileReader;\n" +
5058
			"public class X {\n" +
5059
			"    void foo1() throws Exception {\n" + 
5060
			"        FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + 
5061
			"        try {\n" + 
5062
			"            reader.read();\n" + 
5063
			"            return;\n" + 
5064
			"        } catch (Exception e) {\n" + 
5065
			"            throw new Exception();\n" + 
5066
			"        } finally {\n" + 
5067
			"            reader.close();\n" + 
5068
			"        }\n" + 
5069
			"    }\n" + 
5070
			"\n" + 
5071
			"    void foo2() throws Exception {\n" + 
5072
			"        FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + 
5073
			"        try {\n" + 
5074
			"            reader.read();\n" + 
5075
			"            throw new Exception(); // should not warn here\n" + 
5076
			"        } catch (Exception e) {\n" + 
5077
			"            throw new Exception();\n" + 
5078
			"        } finally {\n" + 
5079
			"            reader.close();\n" + 
5080
			"        }\n" + 
5081
			"    }\n" + 
5082
			"\n" + 
5083
			"    void foo3() throws Exception {\n" + 
5084
			"        FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + 
5085
			"        try {\n" + 
5086
			"            reader.read();\n" + 
5087
			"            throw new Exception();\n" + 
5088
			"        } finally {\n" + 
5089
			"            reader.close();\n" + 
5090
			"        }\n" + 
5091
			"    }\n" + 
5092
			"}\n"
5093
		},
5094
		"----------\n" +
5095
		"1. ERROR in X.java (at line 4)\n" +
5096
		"	FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
5097
		"	           ^^^^^^\n" +
5098
		"Resource 'reader' should be managed by try-with-resource\n" +
5099
		"----------\n" +
5100
		"2. ERROR in X.java (at line 16)\n" +
5101
		"	FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
5102
		"	           ^^^^^^\n" +
5103
		"Resource 'reader' should be managed by try-with-resource\n" +
5104
		"----------\n" +
5105
		"3. ERROR in X.java (at line 28)\n" +
5106
		"	FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
5107
		"	           ^^^^^^\n" +
5108
		"Resource 'reader' should be managed by try-with-resource\n" +
5109
		"----------\n",
5110
		null,
5111
		true,
5112
		options);	
5113
}
5114
// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
5115
// close() nested within finally provides protection for throw
5116
public void test056throw3() {
5117
	Map options = getCompilerOptions();
5118
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5119
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5120
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
5121
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
5122
	this.runNegativeTest(
5123
		new String[] {
5124
			"X.java",
5125
			"import java.io.FileReader;\n" +
5126
			"public class X {\n" +
5127
			"    void foo2x() throws Exception {\n" + 
5128
			"        FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + 
5129
			"        try {\n" + 
5130
			"            reader.read();\n" + 
5131
			"            throw new Exception(); // should not warn here\n" + 
5132
			"        } catch (Exception e) {\n" + 
5133
			"            throw new Exception();\n" + 
5134
			"        } finally {\n" +
5135
			"            if (reader != null)\n" +
5136
			"                 try {\n" + 
5137
			"                     reader.close();\n" +
5138
			"                 } catch (java.io.IOException io) {}\n" + 
5139
			"        }\n" + 
5140
			"    }\n" + 
5141
			"}\n"
5142
		},
5143
		"----------\n" + 
5144
		"1. ERROR in X.java (at line 4)\n" + 
5145
		"	FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + 
5146
		"	           ^^^^^^\n" + 
5147
		"Resource 'reader' should be managed by try-with-resource\n" + 
5148
		"----------\n",
5149
		null,
5150
		true,
5151
		options);	
5152
}
5153
// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
5154
// additional boolean should shed doubt on whether we reach the close() call
5155
public void test056throw4() {
5156
	Map options = getCompilerOptions();
5157
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5158
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5159
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
5160
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
5161
	this.runNegativeTest(
5162
		new String[] {
5163
			"X.java",
5164
			"import java.io.FileReader;\n" +
5165
			"public class X {\n" +
5166
			"    void foo2x(boolean b) throws Exception {\n" + 
5167
			"        FileReader reader = new FileReader(\"file\");\n" + 
5168
			"        try {\n" + 
5169
			"            reader.read();\n" + 
5170
			"            throw new Exception(); // should warn here\n" + 
5171
			"        } catch (Exception e) {\n" + 
5172
			"            throw new Exception(); // should warn here\n" + 
5173
			"        } finally {\n" +
5174
			"            if (reader != null && b)\n" + // this condition is too strong to protect reader
5175
			"                 try {\n" + 
5176
			"                     reader.close();\n" +
5177
			"                 } catch (java.io.IOException io) {}\n" + 
5178
			"        }\n" + 
5179
			"    }\n" + 
5180
			"}\n"
5181
		},
5182
		"----------\n" +
5183
		"1. ERROR in X.java (at line 7)\n" +
5184
		"	throw new Exception(); // should warn here\n" +
5185
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5186
		"Potential resource leak: 'reader' may not be closed at this location\n" +
5187
		"----------\n" +
5188
		"2. ERROR in X.java (at line 9)\n" +
5189
		"	throw new Exception(); // should warn here\n" +
5190
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5191
		"Potential resource leak: 'reader' may not be closed at this location\n" +
5192
		"----------\n",
5193
		null,
5194
		true,
5195
		options);	
5196
}
5197
// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
5198
// similar to test056throw3() but indirectly calling close(), so doubts remain.
5199
public void test056throw5() {
5200
	Map options = getCompilerOptions();
5201
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5202
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
5203
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
5204
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
5205
	this.runNegativeTest(
5206
		new String[] {
5207
			"X.java",
5208
			"import java.io.FileReader;\n" +
5209
			"public class X {\n" +
5210
			"    void foo2x() throws Exception {\n" +
5211
			"        FileReader reader = new FileReader(\"file\");\n" +
5212
			"        try {\n" +
5213
			"            reader.read();\n" +
5214
			"            throw new Exception(); // should warn 'may not' here\n" +
5215
			"        } catch (Exception e) {\n" +
5216
			"            throw new Exception(); // should warn 'may not' here\n" +
5217
			"        } finally {\n" +
5218
			"            doClose(reader);\n" +
5219
			"        }\n" +
5220
			"    }\n" +
5221
			"    void doClose(FileReader r) { try { r.close(); } catch (java.io.IOException ex) {}}\n" + 
5222
			"}\n"
5223
		},
5224
		"----------\n" +
5225
		"1. ERROR in X.java (at line 7)\n" +
5226
		"	throw new Exception(); // should warn \'may not\' here\n" +
5227
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5228
		"Potential resource leak: 'reader' may not be closed at this location\n" +
5229
		"----------\n" +
5230
		"2. ERROR in X.java (at line 9)\n" +
5231
		"	throw new Exception(); // should warn \'may not\' here\n" +
5232
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
5233
		"Potential resource leak: 'reader' may not be closed at this location\n" +
5234
		"----------\n",
5235
		null,
5236
		true,
5237
		options);	
5238
}
5239
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053
5240
public void test057() {
5241
	this.runConformTest(
5242
		new String[] {
5243
			"X.java",
5244
			"public class X implements AutoCloseable {\n" +
5245
			"	@Override\n" +
5246
			"	public void close() throws Exception {\n" +
5247
			"		throw new Exception();\n" +
5248
			"	}\n" +
5249
			"	public static void main(String[] args) {\n" +
5250
			"		final boolean foo;\n" +
5251
			"		try (X a = new X(); X b = new X()) {\n" +
5252
			"			foo = true;\n" +
5253
			"		} catch (final Exception exception) {\n" +
5254
			"			return;\n" +
5255
			"		}\n" +
5256
			"	}\n" +
5257
			"}\n"
5258
		},  "");	
5259
}
5260
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364008
5261
public void test058() {
5262
	this.runConformTest(
5263
		new String[] {
5264
			"X.java",
5265
			"import java.io.ByteArrayOutputStream;\n" +
5266
			"import java.io.FileOutputStream;\n" +
5267
			"import java.io.IOException;\n" +
5268
			"\n" +
5269
			"public class X {\n" +
5270
			"\n" +
5271
			"  public static void main(final String[] args) throws IOException {\n" +
5272
			"    byte[] data;\n" +
5273
			"    try (final ByteArrayOutputStream os = new ByteArrayOutputStream();\n" +
5274
			"         final FileOutputStream out = new FileOutputStream(\"test.dat\")) {\n" +
5275
			"      data = os.toByteArray();\n" +
5276
			"    }\n" +
5277
			"  }\n" +
5278
			"}\n"
5279
		},  "");	
5280
}
5281
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called
5282
public void test059() {
5283
	this.runConformTest(
5284
		new String[] {
5285
			"X.java",
5286
			"import java.io.IOException;\n" +
5287
			"\n" +
5288
			"public class X implements java.lang.AutoCloseable {\n" +
5289
			"  static boolean isOpen = true;\n" +
5290
			"  public static void main(final String[] args) throws IOException {\n" +
5291
			"    foo();\n" +
5292
			"    System.out.println(isOpen);\n" +
5293
			"  }\n" +
5294
			"  static boolean foo() {\n" +
5295
			"    try (final X x = new X()) {\n" +
5296
			"      return x.num() >= 1;\n" +
5297
			"    }\n" +
5298
			"  }\n" +
5299
			"  int num() { return 2; }\n" +
5300
			"  public void close() {\n" +
5301
			"    isOpen = false;\n" +
5302
			"  }\n" +
5303
			"}\n"
5304
		},  
5305
		"false");	
5306
}
5307
5308
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called
5309
public void test060() {
5310
	this.runConformTest(
5311
		new String[] {
5312
			"X.java",
5313
			"public class X implements AutoCloseable {\n" +
5314
			"	static int num = 10 ;\n" +
5315
			"    public static void main(String [] args) throws Exception { \n" +
5316
			"    	System.out.println(foo(1));\n" +
5317
			"    	System.out.println(foo(2));\n" +
5318
			"    	System.out.println(foo(3));\n" +
5319
			"    }\n" +
5320
			"	private static boolean foo(int where) throws Exception {\n" +
5321
			"		final boolean getOut = true;\n" +
5322
			"    	System.out.println(\"Main\");\n" +
5323
			"    	try (X x1 = new X(); X x2 = new X()) {\n" +
5324
			"    		if (where == 1) {\n" +
5325
			"    			return where == 1;\n" +
5326
			"    		}\n" +
5327
			"            System.out.println(\"Outer Try\");\n" +
5328
			"            while (true) {\n" +
5329
			"            	try (Y y1 = new Y(); Y y2 = new Y()) { \n" +
5330
			"            		if (where == 2) {\n" +
5331
			"            			return where == 2;\n" +
5332
			"            		}		\n" +
5333
			"            		System.out.println(\"Middle Try\");\n" +
5334
			"            		try (Z z1 = new Z(); Z z2 = new Z()) {\n" +
5335
			"            			System.out.println(\"Inner Try\");\n" +
5336
			"            			if (getOut) \n" +
5337
			"            				return num >= 10;\n" +
5338
			"            			else\n" +
5339
			"            				break; \n" +
5340
			"            		}\n" +
5341
			"            	}\n" +
5342
			"            }\n" +
5343
			"            System.out.println(\"Out of while\");\n" +
5344
			"        }\n" +
5345
			"		return false;\n" +
5346
			"	}\n" +
5347
			"    public X() {\n" +
5348
			"        System.out.println(\"X::X\");\n" +
5349
			"    }\n" +
5350
			"    @Override\n" +
5351
			"	public void close() throws Exception {\n" +
5352
			"        System.out.println(\"X::~X\");\n" +
5353
			"    }\n" +
5354
			"}\n" +
5355
			"class Y implements AutoCloseable {\n" +
5356
			"    public Y() {\n" +
5357
			"        System.out.println(\"Y::Y\");\n" +
5358
			"    }\n" +
5359
			"    @Override\n" +
5360
			"	public void close() throws Exception {\n" +
5361
			"        System.out.println(\"Y::~Y\");\n" +
5362
			"    }\n" +
5363
			"}\n" +
5364
			"class Z implements AutoCloseable {\n" +
5365
			"    public Z() {\n" +
5366
			"        System.out.println(\"Z::Z\");\n" +
5367
			"    }\n" +
5368
			"    @Override\n" +
5369
			"	public void close() throws Exception {\n" +
5370
			"        System.out.println(\"Z::~Z\");\n" +
5371
			"    }\n" +
5372
			"}\n"
5373
		}, 
5374
		"Main\n" + 
5375
		"X::X\n" + 
5376
		"X::X\n" + 
5377
		"X::~X\n" + 
5378
		"X::~X\n" + 
5379
		"true\n" + 
5380
		"Main\n" + 
5381
		"X::X\n" + 
5382
		"X::X\n" + 
5383
		"Outer Try\n" + 
5384
		"Y::Y\n" + 
5385
		"Y::Y\n" + 
5386
		"Y::~Y\n" + 
5387
		"Y::~Y\n" + 
5388
		"X::~X\n" + 
5389
		"X::~X\n" + 
5390
		"true\n" + 
5391
		"Main\n" + 
5392
		"X::X\n" + 
5393
		"X::X\n" + 
5394
		"Outer Try\n" + 
5395
		"Y::Y\n" + 
5396
		"Y::Y\n" + 
5397
		"Middle Try\n" + 
5398
		"Z::Z\n" + 
5399
		"Z::Z\n" + 
5400
		"Inner Try\n" + 
5401
		"Z::~Z\n" + 
5402
		"Z::~Z\n" + 
5403
		"Y::~Y\n" + 
5404
		"Y::~Y\n" + 
5405
		"X::~X\n" + 
5406
		"X::~X\n" + 
5407
		"true");
5408
}
5409
// Bug 358903 - Filter practically unimportant resource leak warnings
5410
// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly
5411
// a resource wrapper is not closed but the underlying resource is
5412
public void test061a() {
5413
	Map options = getCompilerOptions();
5414
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5415
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5416
	this.runConformTest(
5417
		new String[] {
5418
			"X.java",
5419
			"import java.io.File;\n" +
5420
			"import java.io.BufferedInputStream;\n" +
5421
			"import java.io.FileInputStream;\n" +
5422
			"import java.io.IOException;\n" +
5423
			"public class X {\n" +
5424
			"    void foo() throws IOException {\n" +
5425
			"        File file = new File(\"somefile\");\n" +
5426
			"        FileInputStream fileStream  = new FileInputStream(file);\n" +
5427
			"        BufferedInputStream bis = new BufferedInputStream(fileStream);\n" +
5428
			"        BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" +
5429
			"        System.out.println(bis.available());\n" +
5430
			"        fileStream.close();\n" +
5431
			"    }\n" +
5432
			"    void inline() throws IOException {\n" +
5433
			"        File file = new File(\"somefile\");\n" +
5434
			"        FileInputStream fileStream;\n" +
5435
			"        BufferedInputStream bis = new BufferedInputStream(fileStream = new FileInputStream(file));\n" +
5436
			"        System.out.println(bis.available());\n" +
5437
			"        fileStream.close();\n" +
5438
			"    }\n" +
5439
			"    public static void main(String[] args) throws IOException {\n" +
5440
			"        try {\n" +
5441
			"            new X().foo();\n" +
5442
			"        } catch (IOException ex) {" +
5443
			"            System.out.println(\"Got IO Exception\");\n" +
5444
			"        }\n" +
5445
			"    }\n" +
5446
			"}\n"
5447
		},
5448
		"Got IO Exception",
5449
		null,
5450
		true,
5451
		null,
5452
		options,
5453
		null);
5454
}
5455
// Bug 358903 - Filter practically unimportant resource leak warnings
5456
// a closeable without OS resource is not closed
5457
public void test061b() {
5458
	Map options = getCompilerOptions();
5459
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5460
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5461
	this.runConformTest(
5462
		new String[] {
5463
			"X.java",
5464
			"import java.io.StringReader;\n" +
5465
			"import java.io.IOException;\n" +
5466
			"public class X {\n" +
5467
			"    void foo() throws IOException {\n" +
5468
			"        StringReader string  = new StringReader(\"content\");\n" +
5469
			"        System.out.println(string.read());\n" +
5470
			"    }\n" +
5471
			"    public static void main(String[] args) throws IOException {\n" +
5472
			"        new X().foo();\n" +
5473
			"    }\n" +
5474
			"}\n"
5475
		},
5476
		"99", // character 'c'
5477
		null,
5478
		true,
5479
		null,
5480
		options,
5481
		null);
5482
}
5483
// Bug 358903 - Filter practically unimportant resource leak warnings
5484
// a resource wrapper is not closed but the underlying closeable is resource-free
5485
public void test061c() {
5486
	Map options = getCompilerOptions();
5487
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5488
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5489
	this.runConformTest(
5490
		new String[] {
5491
			"X.java",
5492
			"import java.io.BufferedReader;\n" +
5493
			"import java.io.StringReader;\n" +
5494
			"import java.io.IOException;\n" +
5495
			"public class X {\n" +
5496
			"    void foo() throws IOException {\n" +
5497
			"        StringReader input = new StringReader(\"content\");\n" +
5498
			"        BufferedReader br = new BufferedReader(input);\n" +
5499
			"        BufferedReader doubleWrap = new BufferedReader(br);\n" +
5500
			"        System.out.println(br.read());\n" +
5501
			"    }\n" +
5502
			"    void inline() throws IOException {\n" +
5503
			"        BufferedReader br = new BufferedReader(new StringReader(\"content\"));\n" +
5504
			"        System.out.println(br.read());\n" +
5505
			"    }\n" +
5506
			"    public static void main(String[] args) throws IOException {\n" +
5507
			"        new X().foo();\n" +
5508
			"    }\n" +
5509
			"}\n"
5510
		},
5511
		"99",
5512
		null,
5513
		true,
5514
		null,
5515
		options,
5516
		null);
5517
}
5518
// Bug 358903 - Filter practically unimportant resource leak warnings
5519
// a resource wrapper is not closed neither is the underlying resource
5520
public void test061d() {
5521
	Map options = getCompilerOptions();
5522
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5523
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
5524
	this.runNegativeTest(
5525
		new String[] {
5526
			"X.java",
5527
			"import java.io.File;\n" +
5528
			"import java.io.BufferedInputStream;\n" +
5529
			"import java.io.FileInputStream;\n" +
5530
			"import java.io.IOException;\n" +
5531
			"public class X {\n" +
5532
			"    void foo() throws IOException {\n" +
5533
			"        File file = new File(\"somefile\");\n" +
5534
			"        FileInputStream fileStream  = new FileInputStream(file);\n" +
5535
			"        BufferedInputStream bis = new BufferedInputStream(fileStream);\n" +
5536
			"        BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" +
5537
			"        System.out.println(bis.available());\n" +
5538
			"    }\n" +
5539
			"    void inline() throws IOException {\n" +
5540
			"        File file = new File(\"somefile\");\n" +
5541
			"        BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(file));\n" +
5542
			"        System.out.println(bis2.available());\n" +
5543
			"    }\n" +
5544
			"    public static void main(String[] args) throws IOException {\n" +
5545
			"        try {\n" +
5546
			"            new X().foo();\n" +
5547
			"        } catch (IOException ex) {" +
5548
			"            System.out.println(\"Got IO Exception\");\n" +
5549
			"        }\n" +
5550
			"    }\n" +
5551
			"}\n"
5552
		},
5553
		"----------\n" + 
5554
		"1. ERROR in X.java (at line 10)\n" + 
5555
		"	BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + 
5556
		"	                    ^^^^^^^^^^\n" + 
5557
		"Resource leak: \'doubleWrap\' is never closed\n" + 
5558
		"----------\n" + 
5559
		"2. ERROR in X.java (at line 15)\n" + 
5560
		"	BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(file));\n" + 
5561
		"	                    ^^^^\n" + 
5562
		"Resource leak: \'bis2\' is never closed\n" + 
5563
		"----------\n",
5564
		null,
5565
		true,
5566
		options);
5567
}
5568
// Bug 358903 - Filter practically unimportant resource leak warnings
5569
// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly
5570
// a resource wrapper is closed closing also the underlying resource
5571
public void test061e() {
5572
	Map options = getCompilerOptions();
5573
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5574
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5575
	this.runConformTest(
5576
		new String[] {
5577
			"X.java",
5578
			"import java.io.File;\n" +
5579
			"import java.io.BufferedInputStream;\n" +
5580
			"import java.io.FileInputStream;\n" +
5581
			"import java.io.IOException;\n" +
5582
			"public class X {\n" +
5583
			"    FileInputStream fis;" +
5584
			"    void foo() throws IOException {\n" +
5585
			"        File file = new File(\"somefile\");\n" +
5586
			"        FileInputStream fileStream  = new FileInputStream(file);\n" +
5587
			"        BufferedInputStream bis = new BufferedInputStream(fileStream);\n" +
5588
			"        BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" +
5589
			"        System.out.println(bis.available());\n" +
5590
			"        bis.close();\n" +
5591
			"    }\n" +
5592
			"    void inline() throws IOException {\n" +
5593
			"        File file = new File(\"somefile\");\n" +
5594
			"        BufferedInputStream bis2 = new BufferedInputStream(fis = new FileInputStream(file));\n" + // field assignment
5595
			"        System.out.println(bis2.available());\n" +
5596
			"        bis2.close();\n" +
5597
			"        FileInputStream fileStream  = null;\n" +
5598
			"        BufferedInputStream bis3 = new BufferedInputStream(fileStream = new FileInputStream(file));\n" +
5599
			"        System.out.println(bis3.available());\n" +
5600
			"        bis3.close();\n" +
5601
			"    }\n" +
5602
			"    public static void main(String[] args) throws IOException {\n" +
5603
			"        try {\n" +
5604
			"            new X().foo();\n" +
5605
			"        } catch (IOException ex) {" +
5606
			"            System.out.println(\"Got IO Exception\");\n" +
5607
			"        }\n" +
5608
			"    }\n" +
5609
			"}\n"
5610
		},
5611
		"Got IO Exception",
5612
		null,
5613
		true,
5614
		null,
5615
		options,
5616
		null);
5617
}
5618
// Bug 358903 - Filter practically unimportant resource leak warnings
5619
// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly
5620
// a resource wrapper is closed closing also the underlying resource - original test case
5621
public void test061f() throws IOException {
5622
	Map options = getCompilerOptions();
5623
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5624
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5625
	URL url = FileLocator.toFileURL(FileLocator.find(Platform.getBundle("org.eclipse.jdt.core.tests.compiler"), new Path("META-INF/MANIFEST.MF"), null));
5626
	this.runConformTest(
5627
		new String[] {
5628
			"X.java",
5629
			"import java.io.InputStream;\n" +
5630
			"import java.io.InputStreamReader;\n" +
5631
			"import java.io.BufferedReader;\n" +
5632
			"import java.io.IOException;\n" +
5633
			"import java.net.URL;\n" +
5634
			"public class X {\n" +
5635
			"    boolean loadURL(final URL url) throws IOException {\n" + 
5636
			"        InputStream stream = null;\n" + 
5637
			"        BufferedReader reader = null;\n" + 
5638
			"        try {\n" + 
5639
			"            stream = url.openStream();\n" + 
5640
			"            reader = new BufferedReader(new InputStreamReader(stream));\n" + 
5641
			"            System.out.println(reader.readLine());\n" +
5642
			"        } finally {\n" + 
5643
			"            try {\n" + 
5644
			"                if (reader != null)\n" + 
5645
			"                    reader.close();\n" + 
5646
			"            } catch (IOException x) {\n" + 
5647
			"            }\n" + 
5648
			"        }\n" + 
5649
			"        return false; // 'stream' may not be closed at this location\n" + 
5650
			"    }\n" + 
5651
			"    public static void main(String[] args) throws IOException {\n" +
5652
			"        try {\n" +
5653
			"            new X().loadURL(new URL(\""+url.toString()+"\"));\n" +
5654
			"        } catch (IOException ex) {\n" +
5655
			"            System.out.println(\"Got IO Exception\"+ex);\n" +
5656
			"        }\n" +
5657
			"    }\n" +
5658
			"}\n"
5659
		},
5660
		"Manifest-Version: 1.0",
5661
		null,
5662
		true,
5663
		null,
5664
		options,
5665
		null);
5666
}
5667
// Bug 358903 - Filter practically unimportant resource leak warnings
5668
// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly
5669
// Different points in a resource chain are closed
5670
public void test061g() {
5671
	Map options = getCompilerOptions();
5672
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5673
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5674
	this.runNegativeTest(
5675
		new String[] {
5676
			"X.java",
5677
			"import java.io.File;\n" +
5678
			"import java.io.BufferedInputStream;\n" +
5679
			"import java.io.FileInputStream;\n" +
5680
			"import java.io.IOException;\n" +
5681
			"public class X {\n" +
5682
			"    void closeMiddle() throws IOException {\n" +
5683
			"        File file = new File(\"somefile\");\n" +
5684
			"        FileInputStream fileStream  = new FileInputStream(file);\n" +
5685
			"        BufferedInputStream bis = new BufferedInputStream(fileStream);\n" +
5686
			"        BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" +
5687
			"        System.out.println(bis.available());\n" +
5688
			"        bis.close();\n" +
5689
			"    }\n" +
5690
			"    void closeOuter() throws IOException {\n" +
5691
			"        File file2 = new File(\"somefile\");\n" +
5692
			"        FileInputStream fileStream2  = new FileInputStream(file2);\n" +
5693
			"        BufferedInputStream bis2 = new BufferedInputStream(fileStream2);\n" +
5694
			"        BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" +
5695
			"        System.out.println(bis2.available());\n" +
5696
			"        doubleWrap2.close();\n" +
5697
			"    }\n" +
5698
			"    void neverClosed() throws IOException {\n" +
5699
			"        File file3 = new File(\"somefile\");\n" +
5700
			"        FileInputStream fileStream3  = new FileInputStream(file3);\n" +
5701
			"        BufferedInputStream bis3 = new BufferedInputStream(fileStream3);\n" +
5702
			"        BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" +
5703
			"        System.out.println(doubleWrap3.available());\n" +
5704
			"    }\n" +
5705
			"}\n"
5706
		},
5707
		"----------\n" + 
5708
		"1. ERROR in X.java (at line 26)\n" + 
5709
		"	BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" + 
5710
		"	                    ^^^^^^^^^^^\n" + 
5711
		"Resource leak: \'doubleWrap3\' is never closed\n" + 
5712
		"----------\n",
5713
		null,
5714
		true,
5715
		options);
5716
}
5717
// Bug 358903 - Filter practically unimportant resource leak warnings
5718
// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly
5719
// Different points in a resource chain are potentially closed
5720
public void test061h() {
5721
	Map options = getCompilerOptions();
5722
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5723
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5724
	this.runNegativeTest(
5725
		new String[] {
5726
			"X.java",
5727
			"import java.io.File;\n" +
5728
			"import java.io.BufferedInputStream;\n" +
5729
			"import java.io.FileInputStream;\n" +
5730
			"import java.io.IOException;\n" +
5731
			"public class X {\n" +
5732
			"    void closeMiddle(boolean b) throws IOException {\n" +
5733
			"        File file = new File(\"somefile\");\n" +
5734
			"        FileInputStream fileStream  = new FileInputStream(file);\n" +
5735
			"        BufferedInputStream bis = new BufferedInputStream(fileStream);\n" +
5736
			"        BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" +
5737
			"        System.out.println(bis.available());\n" +
5738
			"        if (b)\n" +
5739
			"            bis.close();\n" +
5740
			"    }\n" +
5741
			"    void closeOuter(boolean b) throws IOException {\n" +
5742
			"        File file2 = new File(\"somefile\");\n" +
5743
			"        FileInputStream fileStream2  = new FileInputStream(file2);\n" +
5744
			"        BufferedInputStream dummy;\n" +
5745
			"        BufferedInputStream bis2 = (dummy = new BufferedInputStream(fileStream2));\n" +
5746
			"        BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" +
5747
			"        System.out.println(bis2.available());\n" +
5748
			"        if (b)\n" +
5749
			"            doubleWrap2.close();\n" +
5750
			"    }\n" +
5751
			"    void potAndDef(boolean b) throws IOException {\n" +
5752
			"        File file3 = new File(\"somefile\");\n" +
5753
			"        FileInputStream fileStream3  = new FileInputStream(file3);\n" +
5754
			"        BufferedInputStream bis3 = new BufferedInputStream(fileStream3);\n" +
5755
			"        BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" +
5756
			"        System.out.println(doubleWrap3.available());\n" +
5757
			"        if (b) bis3.close();\n" +
5758
			"        fileStream3.close();\n" +
5759
			"    }\n" +
5760
			"}\n"
5761
		},
5762
		"----------\n" + 
5763
		"1. ERROR in X.java (at line 10)\n" + 
5764
		"	BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + 
5765
		"	                    ^^^^^^^^^^\n" + 
5766
		"Potential resource leak: \'doubleWrap\' may not be closed\n" + 
5767
		"----------\n" + 
5768
		"2. ERROR in X.java (at line 20)\n" + 
5769
		"	BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" + 
5770
		"	                    ^^^^^^^^^^^\n" + 
5771
		"Potential resource leak: \'doubleWrap2\' may not be closed\n" + 
5772
		"----------\n",
5773
		null,
5774
		true,
5775
		options);
5776
}
5777
// Bug 358903 - Filter practically unimportant resource leak warnings
5778
// local var is re-used for two levels of wrappers
5779
public void test061i() {
5780
	Map options = getCompilerOptions();
5781
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5782
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5783
	this.runNegativeTest(
5784
		new String[] {
5785
			"X.java",
5786
			"import java.io.File;\n" +
5787
			"import java.io.InputStream;\n" +
5788
			"import java.io.BufferedInputStream;\n" +
5789
			"import java.io.FileInputStream;\n" +
5790
			"import java.io.IOException;\n" +
5791
			"public class X {\n" +
5792
			"    void closeMiddle() throws IOException {\n" +
5793
			"        File file = new File(\"somefile\");\n" +
5794
			"        InputStream stream  = new FileInputStream(file);\n" +
5795
			"        stream = new BufferedInputStream(stream);\n" +
5796
			"        InputStream middle;\n" +
5797
			"        stream = new BufferedInputStream(middle = stream);\n" +
5798
			"        System.out.println(stream.available());\n" +
5799
			"        middle.close();\n" +
5800
			"    }\n" +
5801
			"    void closeOuter() throws IOException {\n" +
5802
			"        File file = new File(\"somefile\");\n" +
5803
			"        InputStream stream2  = new FileInputStream(file);\n" +
5804
			"        stream2 = new BufferedInputStream(stream2);\n" +
5805
			"        stream2 = new BufferedInputStream(stream2);\n" +
5806
			"        System.out.println(stream2.available());\n" +
5807
			"        stream2.close();\n" +
5808
			"    }\n" +
5809
			"    void neverClosed() throws IOException {\n" +
5810
			"        File file = new File(\"somefile\");\n" +
5811
			"        InputStream stream3  = new FileInputStream(file);\n" +
5812
			"        stream3 = new BufferedInputStream(stream3);\n" +
5813
			"        stream3 = new BufferedInputStream(stream3);\n" +
5814
			"        System.out.println(stream3.available());\n" +
5815
			"    }\n" +
5816
			"}\n"
5817
		},
5818
		"----------\n" + 
5819
		"1. ERROR in X.java (at line 26)\n" + 
5820
		"	InputStream stream3  = new FileInputStream(file);\n" + 
5821
		"	            ^^^^^^^\n" + 
5822
		"Resource leak: \'stream3\' is never closed\n" + 
5823
		"----------\n",
5824
		null,
5825
		true,
5826
		options);
5827
}
5828
// Bug 358903 - Filter practically unimportant resource leak warnings
5829
// self-wrapping a method argument (caused NPE UnconditionalFlowInfo.markAsDefinitelyNull(..)).
5830
public void test061j() {
5831
	Map options = getCompilerOptions();
5832
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5833
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5834
	this.runConformTest(
5835
		new String[] {
5836
			"X.java",
5837
			"import java.io.InputStream;\n" +
5838
			"import java.io.BufferedInputStream;\n" +
5839
			"import java.io.IOException;\n" +
5840
			"public class X {\n" +
5841
			"    void foo(InputStream stream) throws IOException {\n" +
5842
			"        stream = new BufferedInputStream(stream);\n" +
5843
			"        System.out.println(stream.available());\n" +
5844
			"        stream.close();\n" +
5845
			"    }\n" +
5846
			"    void boo(InputStream stream2) throws IOException {\n" +
5847
			"        stream2 = new BufferedInputStream(stream2);\n" +
5848
			"        System.out.println(stream2.available());\n" +
5849
			"    }\n" +
5850
			"}\n"
5851
		},
5852
		"",
5853
		null,
5854
		true,
5855
		null,
5856
		options,
5857
		null);
5858
}
5859
// Bug 358903 - Filter practically unimportant resource leak warnings
5860
// a wrapper is created in a return statement
5861
public void test061k() throws IOException {
5862
	Map options = getCompilerOptions();
5863
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5864
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5865
	this.runConformTest(
5866
		new String[] {
5867
			"X.java",
5868
			"import java.io.File;\n" +
5869
			"import java.io.FileInputStream;\n" +
5870
			"import java.io.BufferedInputStream;\n" +
5871
			"import java.io.IOException;\n" +
5872
			"public class X {\n" +
5873
			"    BufferedInputStream getReader(File file) throws IOException {\n" +
5874
			"        FileInputStream stream = new FileInputStream(file);\n" +
5875
			"        return new BufferedInputStream(stream);\n" +
5876
			"    }\n" +
5877
			"}\n"
5878
		},
5879
		"",
5880
		null,
5881
		true,
5882
		null,
5883
		options,
5884
		null);
5885
}
5886
// Bug 358903 - Filter practically unimportant resource leak warnings
5887
// a closeable is assigned to a field
5888
public void test061l() throws IOException {
5889
	Map options = getCompilerOptions();
5890
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5891
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5892
	this.runConformTest(
5893
		new String[] {
5894
			"X.java",
5895
			"import java.io.File;\n" +
5896
			"import java.io.FileInputStream;\n" +
5897
			"import java.io.BufferedInputStream;\n" +
5898
			"import java.io.IOException;\n" +
5899
			"public class X {\n" +
5900
			"    BufferedInputStream stream;\n" +
5901
			"    void foo(File file) throws IOException {\n" +
5902
			"        FileInputStream s = new FileInputStream(file);\n" +
5903
			"        stream = new BufferedInputStream(s);\n" +
5904
			"    }\n" +
5905
			"}\n"
5906
		},
5907
		"",
5908
		null,
5909
		true,
5910
		null,
5911
		options,
5912
		null);
5913
}
5914
// Bug 358903 - Filter practically unimportant resource leak warnings
5915
// a closeable is passed to another method in a return statement
5916
// example constructed after org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository#getArtifact(..)
5917
public void test061m() throws IOException {
5918
	Map options = getCompilerOptions();
5919
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5920
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5921
	this.runNegativeTest(
5922
		new String[] {
5923
			"X.java",
5924
			"import java.io.File;\n" +
5925
			"import java.io.FileInputStream;\n" +
5926
			"import java.io.BufferedInputStream;\n" +
5927
			"import java.io.InputStream;\n" +
5928
			"import java.io.IOException;\n" +
5929
			"public class X {\n" +
5930
			"    BufferedInputStream stream;\n" +
5931
			"    BufferedInputStream foo(File file) throws IOException {\n" +
5932
			"        FileInputStream s = new FileInputStream(file);\n" +
5933
			"        return check(new BufferedInputStream(s));\n" +
5934
			"    }\n" +
5935
			"    BufferedInputStream foo2(FileInputStream s, File file) throws IOException {\n" +
5936
			"        s = new FileInputStream(file);\n" +
5937
			"        return check(s);\n" +
5938
			"    }\n" +
5939
			"    BufferedInputStream foo3(InputStream s) throws IOException {\n" +
5940
			"        s = check(s);\n" +
5941
			"        return check(s);\n" +
5942
			"    }\n" +
5943
			"    BufferedInputStream check(InputStream s) { return null; }\n" +
5944
			"}\n"
5945
		},
5946
		// TODO: also these warnings *might* be avoidable by detecting check(s) as a wrapper creation?? 
5947
		"----------\n" + 
5948
		"1. ERROR in X.java (at line 14)\n" + 
5949
		"	return check(s);\n" + 
5950
		"	^^^^^^^^^^^^^^^^\n" + 
5951
		"Potential resource leak: \'s\' may not be closed at this location\n" + 
5952
		"----------\n" + 
5953
		"2. ERROR in X.java (at line 18)\n" + 
5954
		"	return check(s);\n" + 
5955
		"	^^^^^^^^^^^^^^^^\n" + 
5956
		"Potential resource leak: \'s\' may not be closed at this location\n" + 
5957
		"----------\n",
5958
		null,
5959
		true,
5960
		options);
5961
}
5962
// Bug 362331 - Resource leak not detected when closeable not assigned to variable
5963
// a resource is never assigned
5964
public void test062a() throws IOException {
5965
	Map options = getCompilerOptions();
5966
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5967
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5968
	this.runNegativeTest(
5969
		new String[] {
5970
			"X.java",
5971
			"import java.io.File;\n" +
5972
			"import java.io.FileOutputStream;\n" +
5973
			"import java.io.IOException;\n" +
5974
			"public class X {\n" +
5975
			"    void foo() throws IOException {\n" +
5976
			"        new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).write(1);\n" + 
5977
			"    }\n" +
5978
			"}\n"
5979
		},
5980
		"----------\n" + 
5981
		"1. ERROR in X.java (at line 6)\n" + 
5982
		"	new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).write(1);\n" + 
5983
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
5984
		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
5985
		"----------\n",
5986
		null,
5987
		true,
5988
		options);
5989
}
5990
// Bug 362331 - Resource leak not detected when closeable not assigned to variable
5991
// a freshly allocated resource is immediately closed
5992
public void test062b() throws IOException {
5993
	Map options = getCompilerOptions();
5994
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
5995
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
5996
	this.runConformTest(
5997
		new String[] {
5998
			"X.java",
5999
			"import java.io.File;\n" +
6000
			"import java.io.FileOutputStream;\n" +
6001
			"import java.io.IOException;\n" +
6002
			"public class X {\n" +
6003
			"    void foo() throws IOException {\n" +
6004
			"        new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).close();\n" + 
6005
			"    }\n" +
6006
			"}\n"
6007
		},
6008
		"",
6009
		null,
6010
		true,
6011
		null,
6012
		options,
6013
		null);
6014
}
6015
// Bug 362331 - Resource leak not detected when closeable not assigned to variable
6016
// a resource is directly passed to another method
6017
public void test062c() throws IOException {
6018
	Map options = getCompilerOptions();
6019
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6020
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6021
	this.runConformTest(
6022
		new String[] {
6023
			"X.java",
6024
			"import java.io.File;\n" +
6025
			"import java.io.FileOutputStream;\n" +
6026
			"import java.io.IOException;\n" +
6027
			"public class X {\n" +
6028
			"    void foo() throws IOException {\n" +
6029
			"        writeIt(new FileOutputStream(new File(\"C:\\temp\\foo.txt\")));\n" + 
6030
			"    }\n" +
6031
			"    void writeIt(FileOutputStream fos) throws IOException {\n" +
6032
			"        fos.write(1);\n" +
6033
			"        fos.close();\n" +
6034
			"    }\n" +
6035
			"}\n"
6036
		},
6037
		"",
6038
		null,
6039
		true,
6040
		null,
6041
		options,
6042
		null);
6043
}
6044
// Bug 362331 - Resource leak not detected when closeable not assigned to variable
6045
// a resource is not used
6046
public void test062d() throws IOException {
6047
	Map options = getCompilerOptions();
6048
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6049
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6050
	this.runNegativeTest(
6051
		new String[] {
6052
			"X.java",
6053
			"import java.io.File;\n" +
6054
			"import java.io.FileOutputStream;\n" +
6055
			"import java.io.IOException;\n" +
6056
			"public class X {\n" +
6057
			"    void foo() throws IOException {\n" +
6058
			"        new FileOutputStream(new File(\"C:\\temp\\foo.txt\"));\n" + 
6059
			"    }\n" +
6060
			"}\n"
6061
		},
6062
		"----------\n" + 
6063
		"1. ERROR in X.java (at line 6)\n" + 
6064
		"	new FileOutputStream(new File(\"C:\\temp\\foo.txt\"));\n" + 
6065
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
6066
		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
6067
		"----------\n",
6068
		null,
6069
		true,
6070
		options);
6071
}
6072
// Bug 362332 - Only report potential leak when closeable not created in the local scope
6073
// a wrapper is obtained from another method
6074
public void test063a() throws IOException {
6075
	Map options = getCompilerOptions();
6076
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6077
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6078
	this.runNegativeTest(
6079
		new String[] {
6080
			"X.java",
6081
			"import java.io.File;\n" +
6082
			"import java.io.FileInputStream;\n" +
6083
			"import java.io.BufferedInputStream;\n" +
6084
			"import java.io.IOException;\n" +
6085
			"public class X {\n" +
6086
			"    void read(File file) throws IOException {\n" +
6087
			"        FileInputStream stream = new FileInputStream(file);\n" +
6088
			"        BufferedInputStream bis = new BufferedInputStream(stream); // never since reassigned\n" +
6089
			"        FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" +
6090
			"        bis = getReader(stream2); // unsure since obtained from method\n" +
6091
			"        bis.available();\n" +
6092
			"    }\n" +
6093
			"    BufferedInputStream getReader(FileInputStream stream) throws IOException {\n" +
6094
			"        return new BufferedInputStream(stream);\n" +
6095
			"    }\n" +
6096
			"}\n"
6097
		},
6098
		"----------\n" + 
6099
		"1. ERROR in X.java (at line 8)\n" + 
6100
		"	BufferedInputStream bis = new BufferedInputStream(stream); // never since reassigned\n" + 
6101
		"	                    ^^^\n" + 
6102
		"Resource leak: \'bis\' is never closed\n" + 
6103
		"----------\n" + 
6104
		"2. ERROR in X.java (at line 9)\n" + 
6105
		"	FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" + 
6106
		"	                ^^^^^^^\n" + 
6107
		"Potential resource leak: \'stream2\' may not be closed\n" + 
6108
		"----------\n" + 
6109
		"3. ERROR in X.java (at line 10)\n" + 
6110
		"	bis = getReader(stream2); // unsure since obtained from method\n" + 
6111
		"	^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
6112
		"Potential resource leak: \'bis\' may not be closed\n" + 
6113
		"----------\n",
6114
		null,
6115
		true,
6116
		options);
6117
}
6118
// Bug 362332 - Only report potential leak when closeable not created in the local scope
6119
// a wrapper is obtained from a field read
6120
public void test063b() throws IOException {
6121
	Map options = getCompilerOptions();
6122
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6123
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6124
	this.runConformTest(
6125
		new String[] {
6126
			"X.java",
6127
			"import java.io.FileInputStream;\n" +
6128
			"import java.io.BufferedInputStream;\n" +
6129
			"import java.io.IOException;\n" +
6130
			"public class X {\n" +
6131
			"    FileInputStream stream;\n" +
6132
			"    void read() throws IOException {\n" +
6133
			"        FileInputStream s = this.stream;\n" +
6134
			"        BufferedInputStream bis = new BufferedInputStream(s); // don't complain since s is obtained from a field\n" +
6135
			"        bis.available();\n" +
6136
			"    }\n" +
6137
			"}\n"
6138
		},
6139
		"",
6140
		null,
6141
		true,
6142
		null,
6143
		options,
6144
		null);
6145
}
6146
// Bug 362332 - Only report potential leak when closeable not created in the local scope
6147
// a wrapper is assigned to a field
6148
public void test063c() throws IOException {
6149
	Map options = getCompilerOptions();
6150
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6151
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6152
	this.runConformTest(
6153
		new String[] {
6154
			"X.java",
6155
			"import java.io.FileInputStream;\n" +
6156
			"import java.io.BufferedInputStream;\n" +
6157
			"import java.io.IOException;\n" +
6158
			"public class X {\n" +
6159
			"    BufferedInputStream stream;\n" +
6160
			"    void read() throws IOException {\n" +
6161
			"        FileInputStream s = new FileInputStream(\"somefile\");\n" +
6162
			"        BufferedInputStream bis = new BufferedInputStream(s);\n" +
6163
			"        this.stream = bis;\n" +
6164
			"    }\n" +
6165
			"}\n"
6166
		},
6167
		"",
6168
		null,
6169
		true,
6170
		null,
6171
		options,
6172
		null);
6173
}
6174
// Bug 362332 - Only report potential leak when closeable not created in the local scope
6175
// a resource is obtained as a method argument and/or assigned with a cast
6176
public void test063d() throws IOException {
6177
	Map options = getCompilerOptions();
6178
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
6179
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
6180
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
6181
	this.runNegativeTest(
6182
		new String[] {
6183
			"X.java",
6184
			"import java.io.FileInputStream;\n" +
6185
			"import java.io.BufferedInputStream;\n" +
6186
			"import java.io.InputStream;\n" +
6187
			"import java.io.IOException;\n" +
6188
			"public class X {\n" +
6189
			"    void foo( InputStream input) throws IOException {\n" +
6190
			"        FileInputStream input1  = (FileInputStream)input;\n" +
6191
			"        System.out.println(input1.read());\n" +
6192
			"        input.close();\n" + // don't propose t-w-r for argument
6193
			"    }\n" +
6194
			"    void foo() throws IOException {\n" +
6195
			"        InputStream input = new FileInputStream(\"somefile\");\n" + 
6196
			"        FileInputStream input1  = (FileInputStream)input;\n" + 
6197
			"        System.out.println(input1.read());\n" + 
6198
			"        input.close();\n" + // do propose t-w-r, not from a method argument
6199
			"    }\n" +
6200
			"    void foo3( InputStream input, InputStream input2) throws IOException {\n" +
6201
			"        FileInputStream input1  = (FileInputStream)input;\n" + // still don't claim because obtained from outside
6202
			"        System.out.println(input1.read());\n" +
6203
			"        BufferedInputStream bis = new BufferedInputStream(input2);\n" +
6204
			"        System.out.println(bis.read());\n" +
6205
			"    }\n" +
6206
			"}\n"
6207
		},
6208
		"----------\n" + 
6209
		"1. ERROR in X.java (at line 12)\n" + 
6210
		"	InputStream input = new FileInputStream(\"somefile\");\n" + 
6211
		"	            ^^^^^\n" + 
6212
		"Resource \'input\' should be managed by try-with-resource\n" + 
6213
		"----------\n",
6214
		null,
6215
		true,
6216
		options);
6217
	
6218
}
3630
}
6219
public static Class testClass() {
3631
public static Class testClass() {
6220
	return TryWithResourcesStatementTest.class;
3632
	return TryWithResourcesStatementTest.class;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java (-1 / +4 lines)
Lines 52-58 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl Link Here
52
					.analyseCode(currentScope, flowContext, flowInfo)
52
					.analyseCode(currentScope, flowContext, flowInfo)
53
					.unconditionalInits();
53
					.unconditionalInits();
54
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
54
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
55
			flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, this.resolvedType);
55
			if (!(this.resolvedType instanceof ReferenceBinding 
56
					&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable))) { // allocation of wrapped closeables is analyzed specially
57
				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
58
			}
56
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
59
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
57
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
60
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
58
			}
61
			}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java (-5 / +2 lines)
Lines 167-173 public class FakedTrackingVariable extends LocalDeclaration { Link Here
167
		if (rhs instanceof AllocationExpression) {
167
		if (rhs instanceof AllocationExpression) {
168
			closeTracker = local.closeTracker;
168
			closeTracker = local.closeTracker;
169
			if (closeTracker == null) {
169
			if (closeTracker == null) {
170
				if (isAnyCloseable(rhs.resolvedType)) {
170
				if (rhs.resolvedType != TypeBinding.NULL) { // not NULL means valid closeable as per method precondition
171
					closeTracker = new FakedTrackingVariable(local, location);
171
					closeTracker = new FakedTrackingVariable(local, location);
172
				}					
172
				}					
173
			}
173
			}
Lines 495-504 public class FakedTrackingVariable extends LocalDeclaration { Link Here
495
	 * (as argument to a method/ctor call or as a return value from the current method), 
495
	 * (as argument to a method/ctor call or as a return value from the current method), 
496
	 * and thus should be considered as potentially closed.
496
	 * and thus should be considered as potentially closed.
497
	 */
497
	 */
498
	public static FlowInfo markPassedToOutside(BlockScope scope, Expression expression, FlowInfo flowInfo, TypeBinding allocatedType) {	
498
	public static FlowInfo markPassedToOutside(BlockScope scope, Expression expression, FlowInfo flowInfo) {	
499
		if ((allocatedType instanceof ReferenceBinding) // only set when called from AllocationExpression
500
				&& ((ReferenceBinding) allocatedType).hasTypeBit(TypeIds.BitWrapperCloseable))
501
			return flowInfo; // allocation of wrapped closeables is analyzed specially
502
		
499
		
503
		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
500
		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
504
		if (trackVar != null) {
501
		if (trackVar != null) {
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-1 / +1 lines)
Lines 99-105 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl Link Here
99
			}
99
			}
100
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
100
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
101
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
101
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
102
			flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, null);
102
			flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
103
		}
103
		}
104
		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
104
		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
105
	}
105
	}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java (-1 / +1 lines)
Lines 82-88 public class QualifiedAllocationExpression extends AllocationExpression { Link Here
82
		if (this.arguments != null) {
82
		if (this.arguments != null) {
83
			for (int i = 0, count = this.arguments.length; i < count; i++) {
83
			for (int i = 0, count = this.arguments.length; i < count; i++) {
84
				// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
84
				// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
85
				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, null);
85
				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
86
				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
86
				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
87
				if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
87
				if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
88
					this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
88
					this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (-1 / +2 lines)
Lines 1003-1009 public void checkUnclosedCloseables(FlowInfo flowInfo, ASTNode location, BlockSc Link Here
1003
		return;
1003
		return;
1004
	}
1004
	}
1005
	if (location != null && flowInfo.reachMode() != 0) return;
1005
	if (location != null && flowInfo.reachMode() != 0) return;
1006
	for (int i=0; i<this.trackingVariables.size(); i++) {
1006
	int trackVarsLen = this.trackingVariables.size();
1007
	for (int i=0; i<trackVarsLen; i++) {
1007
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1008
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1008
		if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding))
1009
		if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding))
1009
			continue; // reporting against a specific location, resource is null at this flow, don't complain
1010
			continue; // reporting against a specific location, resource is null at this flow, don't complain

Return to bug 358903