With the new binary compatibility ABI, it is possible for compiled code to be loaded into an environment where dependent classes are different from the classes visible to the compiler at bytecode verification time. This can be used to circumvent type safety in some situations. One potential fix is for the compiler to emit "verifier assertions" that must be checked at runtime. For example these could be checked at class preparation time. It isn't completely clear what assertions will need checking. It might suffice to check extends/implements requirements implied by the bytecode (and checked by the verifier). It could also be worthwhile to look at the JSR relating to "split verification". I haven't done this yet due to the strange license on this JSR. Beware of this before downloading.
Confirmed.
FYI, I managed to find a slide show about "split verification" that isn't under an obnoxious license. Split verification is basically a proposal for having the compiler emit type maps into the generated bytecode, so that the runtime verifier can do much less work to verify bytecode. So, this isn't exactly what we need. Instead we need something that accepts many constructs at verification time (e.g., always return true when asked if "is method X in class Y" or "does class X implement interface Y"), then builds a list of such assertions to be checked when the resulting object file is linked at runtime.
At present, the compiler on the gcj-abi-2-dev-branch output warning messages when it fails to find types that it needs to check for compatibility. We need to change this so that type compatibility checks are output into the <init> section of the file.
We also need to make sure that a class isn't overriding a final methos somewhere in the superclass chain.
If a class fails a static assertion (e.g., stack overflow in a method), gcj should not fail outright. Instead it should continue to generate code which throws a verification failure at the appropriate time. At least, this is what we want for gcj-jit. Otherwise, if gcj does exit with a failure, we will just fall back on the bytecode and uselessly verify it a second time. This can easily be done by adding an always-fail assertion to the assertion table. Either a special assert(0), or just assert something that can't be true, like "Object extends String"
Type assertions are noe generated and checked. However, the format for encoding these assertions isn't at all compact.
Job done.
Fixed on the mainline by merge of the BC branch.