JDK-8077810 : java.lang.VerifyError: Bad type on operand stack in runtime
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2015-04-13
  • Updated: 2018-02-06
  • Resolved: 2018-02-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10
10Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux unit-663 3.16.0-33-generic #44-Ubuntu SMP Thu Mar 12 12:19:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
public interface Main<T>  {
    T create(T other);
 
    class Poly<T extends Main<T>> implements Main<Poly<T>> {
        static final Poly<?> INSTANCE = new Poly() {
        };
 
        public Poly<T> create(Poly<T> other) {
            return new Poly<>();
        }
    }
 
    static void main(String[] args) {
        new Poly();
    }
}


Code compiles correctly, but fails in runtime:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    Main$Poly$1.create(Ljava/lang/Object;)Ljava/lang/Object; @2: invokespecial
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'Main$Poly'
  Current Frame:
    bci: @2
    flags: { }
    locals: { 'Main$Poly$1', 'java/lang/Object' }
    stack: { 'Main$Poly$1', 'java/lang/Object' }
  Bytecode:
    0x0000000: 2a2b b700 02b0                         

	at Main$Poly.<clinit>(Main.java:5)
	at Main.main(Main.java:14)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run this code
public interface Main<T>  {
    T create(T other);
 
    class Poly<T extends Main<T>> implements Main<Poly<T>> {
        static final Poly<?> INSTANCE = new Poly() {
        };
 
        public Poly<T> create(Poly<T> other) {
            return new Poly<>();
        }
    }
 
    static void main(String[] args) {
        new Poly();
    }
}



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
empty ouput, no fail
ACTUAL -
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    Main$Poly$1.create(Ljava/lang/Object;)Ljava/lang/Object; @2: invokespecial
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'Main$Poly'
  Current Frame:
    bci: @2
    flags: { }
    locals: { 'Main$Poly$1', 'java/lang/Object' }
    stack: { 'Main$Poly$1', 'java/lang/Object' }
  Bytecode:
    0x0000000: 2a2b b700 02b0                         

	at Main$Poly.<clinit>(Main.java:5)
	at Main.main(Main.java:14)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    Main$Poly$1.create(Ljava/lang/Object;)Ljava/lang/Object; @2: invokespecial
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'Main$Poly'
  Current Frame:
    bci: @2
    flags: { }
    locals: { 'Main$Poly$1', 'java/lang/Object' }
    stack: { 'Main$Poly$1', 'java/lang/Object' }
  Bytecode:
    0x0000000: 2a2b b700 02b0                         

	at Main$Poly.<clinit>(Main.java:5)
	at Main.main(Main.java:14)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public interface Main<T>  {
    T create(T other);
 
    class Poly<T extends Main<T>> implements Main<Poly<T>> {
        static final Poly<?> INSTANCE = new Poly() {
        };
 
        public Poly<T> create(Poly<T> other) {
            return new Poly<>();
        }
    }
 
    static void main(String[] args) {
        new Poly();
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
no workaround


Comments
For the record, here is the code generated for the offending bridge method in jdk9: (the main class has been renamed to X) public java.lang.Object create(java.lang.Object); descriptor: (Ljava/lang/Object;)Ljava/lang/Object; flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: invokespecial #2 // Method X$Poly.create:(LX$Poly;)LX$Poly; 5: areturn Note that bci 2 is the instruction that fails to pass verification and fails with "Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'X$Poly'" And here is the code produced on tip: public java.lang.Object create(java.lang.Object); descriptor: (Ljava/lang/Object;)Ljava/lang/Object; flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: checkcast #2 // class X$Poly 5: invokespecial #3 // Method X$Poly.create:(LX$Poly;)LX$Poly; 8: areturn The checkcast inserted by the tip compiler at bci 2 addresses the problem.
06-02-2018

Same as JDK-8189659
05-02-2018

The verify error that is complained about is not reproducible anymore post the fix for JDK-8189659
05-02-2018

I have two patches for this problem, one that is very simple, works but is probably wrong :), one that is much more complicated, works, is probably right, but it is questionable whether it worth it. After dozen years and more of frowning upon raw types, it is debatable if javac should bend over backwards to support a corner case involving raw types. My feeling is that it is not and perhaps this should be closed as won't fix,
26-09-2016

Reproduced on JDK9 tip. I offer to follow up with investigation.
15-04-2015

1) Run the attached test cases (Main.java) 2) Checked this on Linux and Windows 7 (64-bit) with JDK 8u31, 8u40, 8u60 ea b07 and 9 ea b57. **************************************************************************************** 8u31: FAIL 8u40: FAIL 8u60 b07: FAIL 9 ea b57: FAIL ****************************************************************************************** Output of the testcase with 8u40: >java Main Exception in thread "main" java.lang.VerifyError: Bad type on operand stack Exception Details: Location: Main$Poly$1.create(Ljava/lang/Object;)Ljava/lang/Object; @2: invokespecial Reason: Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'Main$Poly' Current Frame: bci: @2 flags: { } locals: { 'Main$Poly$1', 'java/lang/Object' } stack: { 'Main$Poly$1', 'java/lang/Object' } Bytecode: 0000000: 2a2b b700 02b0 at Main$Poly.<clinit>(Main.java:5) at Main.main(Main.java:14) ***************************************** Result: The runtime exception is reproducible with JDK 8u40 and 9 ea b57.
15-04-2015