Bug 210425 - [1.5][compiler] @SuppressWarnings("unchecked") not considered necessary for unconstrained generic parameters
Summary: [1.5][compiler] @SuppressWarnings("unchecked") not considered necessary for ...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M5   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-20 13:01 EST by Ed Willink CLA
Modified: 2008-02-28 07:36 EST (History)
3 users (show)

See Also:


Attachments
Proposed patch (14.17 KB, patch)
2008-02-01 09:49 EST, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Willink CLA 2007-11-20 13:01:41 EST
The following (from org.eclipse.ocl.parser.AbstractOCLAnalyzer).

        protected OCLExpression<C> getLoopBody(OCLExpression<C> expr) {
                return ((LoopExp<C, PM>) expr).getBody();
        }

needs an @SuppressWarnings("unchecked") with Eclipse 3.3.1.

3.4M3 reports the cast as unnecessary. Not so.

The LoopExp is run-time checked.

The <C,?> is ok if the above check is ok since LoopExp<C,?> extends
OCLExpression<C> - rather powerful and nice that you can now do this.

The <?,PM> cannot be checked since getBody is an interface method, so it is not
possible to prove that all implementations of getBody() are independent of the
unconstrained PM type.

[To reproduce create an Eclipse 3.4M3 with EMF M3 and MDT OCL M3. Import the
org.eclipse.ocl plugin as source and view the org.eclipse.ocl.parser.AbstractOCLAnalyzer.getLoopBody method.]
Comment 1 Philipe Mulet CLA 2007-11-20 13:14:24 EST
Can you create a self-contained testcase ? Or provide details on how to find the sources needed ? (ideally a small testcase is better) 
Comment 2 Ed Willink CLA 2007-11-20 13:24:15 EST
EMF and MDT OCL are both Europa projects.

EMF is at http://www.eclipse.org/downloads/download.php?file=/modeling/emf/emf/downloads/drops/2.4.0/S200711062140/emf-sdo-xsd-SDK-2.4.0M3.zip

MDT OCL is at http://www.eclipse.org/downloads/download.php?file=/modeling/mdt/ocl/downloads/drops/1.2.0/S200711121359/mdt-ocl-SDK-1.2.0M3.zip

I thought the Eclipse code was better since it was standard, subject to regression failures. The OCL warnings are now almost entirely due to new cast checking behaviour. Since OCL's use of generics is unusually heavy, it may provide you with some interesting cases.
Comment 3 Philipe Mulet CLA 2007-11-21 13:11:56 EST
Will check. 3.4 checks near cast conversions are stricter than it used to be, and thus should better spot invalid cast early on.

Now, maybe some regressions got introduced.
Comment 4 Philipe Mulet CLA 2007-11-22 04:10:41 EST
Maxime - pls try to isolate a testcase, and validate whether or not we really have an issue (once clarified, pls reassign to me)
Comment 5 Maxime Daniel CLA 2007-11-22 08:55:15 EST
Applying the steps cited in initial post to the material of comment #2 does result into the unchecked warning not being raised, as noticed.

I isolated a much shorter test case (see below) that has the same behavior (no unchecked warning) and looks very like the full test case locally. It also seem to match the arguments given in the initial comment, and it shows a difference to javac, that raises an unchecked warning (tested for 1.5.0_12_b04, 6_03_b02, 7_b17).

However, the said reduced test case does not raise an unchecked warning either with 3.3.1.

When I attempted to use the complete test case against 3.3.1, I faced the following problems:
- the provided versions of EMF and OCL cannot be used with 3.3.1 because of plugin dependencies;
- the most advanced versions of EMF and OCL that are available and deemed 3.3.1 compatible do not include the org.eclipse.ocl.parser.AbstractOCLAnalyzer class (indeed, OCL had a package named org.eclipse.ocl.internal.parser for its parser at that time, which had no AbstractOCLAnalyzer class); I located a class OCLParser that has the getLoopBody method, but, commenting out the SuppressWarning does not make the compiler raise the unchecked warning.

(aka
//	@SuppressWarnings("unchecked")
	private OCLExpression<C> getLoopBody(OCLExpression<C> expr) {
		return ((LoopExp<C, PM>) expr).getBody();
	}
has no unchecked warning)

Net result is that I have a reduced test case that shows no regression, hence it does not match the issue as reported here. *But* I could not reproduce the issue as reported by using EMF and OCL either. An indication of a way to get a version of OCL that would compile under 3.3.1 and exhibit the behavior cited in the initial comment would help. Without it, we would probably have to consider that either the regression is older than that, or that we have no regression at all, which would leave us with a difference to javac, that we'd need to investigate as such.

public abstract class X<T, U> {
  J<T, U> foo(I<T> i) {
	return (J<T, U>) i; // javac raises unchecked here, we don't
  }
}
interface I<T> {
}
interface J<T, U> extends I<T> {
}
Comment 6 Christian Damus CLA 2007-11-22 09:07:09 EST
Hi, Maxime,

You did, indeed, find the right correspondent in the older OCL code.  If it helps you, you can check out the same OCL plug-ins using the R1_1_1 tag to compile with Eclipse 3.3.1 and EMF 2.3.1.

Thanks for looking into this so thoroughly!
Comment 7 Maxime Daniel CLA 2007-11-22 09:45:30 EST
As far as the spec is concerned, now.

JLS § 5.1.9 defines unchecked conversion as involving a raw type and a generic type (which further has at least one of his parameters that is not an unbounded wildcard). The reduced test case and the original test case both involve generic types only, and hence to not involve unchecked conversion.

Considering the discussion of heap pollution in § 4.12.2.1 though, we would be encouraged to consider whether the said code could lead to heap pollution, and, if so, decide that we must report an unchecked warning despite § 5.1.9.
The following extended test case proves the heap pollution possibility:
public class X {
  public static void main(String[] args) {
	U1 u = new U1();
	Z<String, U1> j1 = new Z<String, U1> (u);
	Z<String, U2> j2 = new Z<String, U2> (new U2());
	Y<String, U1> y = new Y<String, U1> () {};
	y.foo(j1).getF().foo();
	y.foo(j2).getF().foo(); // heap pollution: we get a CCE because we return a U2
  }
}
abstract class Y<T, U> {
  J<T, U> foo(I<T> i) {
	return (J<T, U>) i;
  }
}
interface I<T> {
}
interface J<T, U> extends I<T> {
  U getF();
}
class Z<T, U> implements J<T, U> {
  U f;
  Z(U p) {
	this.f = p;
  }
  public U getF() {
	return this.f;
  }
}
class U1 {
  void foo() {
  }
}
class U2 {
}

Accordingly, we could consider following javac and raising an unchecked warning for the cast.
Comment 8 Maxime Daniel CLA 2007-11-22 09:49:36 EST
At Philippe's request, also tried:
public class X <T, U> {
  K<T> foo(I<T> i) {
	return (K<T>) i;
  }
}
interface I<T> {
}
interface J<T, U> extends I<T> {
}
interface K<T> extends J<T, String> {
}

Neither javac nor us bark on this one.
Comment 9 Philipe Mulet CLA 2008-02-01 09:35:03 EST
Added GenericTypeTest#test1284-1289
Comment 10 Philipe Mulet CLA 2008-02-01 09:39:48 EST
Also added GenericTypeTest#test1290 for comment 8 (which I believe should emit no warning, as we do currently).
Comment 11 Philipe Mulet CLA 2008-02-01 09:49:16 EST
Created attachment 88557 [details]
Proposed patch
Comment 12 Philipe Mulet CLA 2008-02-01 12:05:03 EST
Ed - I'd love to hear back from you once you get a hold on 3.4M5 to assess whether these issues are entirely gone ? Your testcases seemed quite interesting.

Released for 3.4M5
Fixed
Comment 13 Jerome Lanneluc CLA 2008-02-04 13:10:32 EST
Verified for 3.4M5 using I20080204-0010
Comment 14 Ed Willink CLA 2008-02-18 02:29:20 EST
This looks very promising.

The M5 version of org.eclipse.ocl.parser.AbstractOCLAnalyzer now has a good sprinkling of warnings all of which seem right. Modifying a few annotations changes the warnings sensibly. This would appear to work for both one and two argument generics.

No new problems apparent elsewhere.
Comment 15 Philipe Mulet CLA 2008-02-28 07:36:11 EST
Released fix in 3.3.x maintenance branch (post 3.3.2)