8210495: compiler crashes because of illegal signature in otherwise legal code

Disable strict verification of compiler signatures when they do not affect generated bytecode

Reviewed-by: vromero
This commit is contained in:
Maurizio Cimadamore 2018-09-07 15:56:21 +01:00
parent 660f6b448b
commit c0d51dc514
3 changed files with 114 additions and 11 deletions
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac/lambda/8210495

@ -5022,6 +5022,10 @@ public class Types {
this.types = types;
}
protected void reportIllegalSignature(Type t) {
throw new InvalidSignatureException(t);
}
/**
* Assemble signature of given type in string buffer.
*/
@ -5056,7 +5060,7 @@ public class Types {
break;
case CLASS:
if (type.isCompound()) {
throw new InvalidSignatureException(type);
reportIllegalSignature(type);
}
append('L');
assembleClassSig(type);
@ -5101,7 +5105,7 @@ public class Types {
}
case TYPEVAR:
if (((TypeVar)type).isCaptured()) {
throw new InvalidSignatureException(type);
reportIllegalSignature(type);
}
append('T');
append(type.tsym.name);

@ -25,6 +25,9 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@ -2031,7 +2034,7 @@ public class LambdaToMethod extends TreeTranslator {
owner.type != null ||
directlyEnclosingLambda() != null);
if (owner.type != null) {
buf.append(typeSig(owner.type));
buf.append(typeSig(owner.type, true));
buf.append(":");
}
@ -2047,7 +2050,7 @@ public class LambdaToMethod extends TreeTranslator {
//add captured locals info: type, name, order
for (Symbol fv : getSymbolMap(CAPTURED_VAR).keySet()) {
if (fv != self) {
buf.append(typeSig(fv.type));
buf.append(typeSig(fv.type, true));
buf.append(" ");
buf.append(fv.flatName());
buf.append(",");
@ -2433,15 +2436,31 @@ public class LambdaToMethod extends TreeTranslator {
*/
private String typeSig(Type type) {
L2MSignatureGenerator sg = new L2MSignatureGenerator();
sg.assembleSig(type);
return sg.toString();
return typeSig(type, false);
}
private String typeSig(Type type, boolean allowIllegalSignature) {
try {
L2MSignatureGenerator sg = new L2MSignatureGenerator(allowIllegalSignature);
sg.assembleSig(type);
return sg.toString();
} catch (InvalidSignatureException ex) {
Symbol c = attrEnv.enclClass.sym;
log.error(Errors.CannotGenerateClass(c, Fragments.IllegalSignature(c, ex.type())));
return "<ERRONEOUS>";
}
}
private String classSig(Type type) {
L2MSignatureGenerator sg = new L2MSignatureGenerator();
sg.assembleClassSig(type);
return sg.toString();
try {
L2MSignatureGenerator sg = new L2MSignatureGenerator(false);
sg.assembleClassSig(type);
return sg.toString();
} catch (InvalidSignatureException ex) {
Symbol c = attrEnv.enclClass.sym;
log.error(Errors.CannotGenerateClass(c, Fragments.IllegalSignature(c, ex.type())));
return "<ERRONEOUS>";
}
}
/**
@ -2454,8 +2473,22 @@ public class LambdaToMethod extends TreeTranslator {
*/
StringBuilder sb = new StringBuilder();
L2MSignatureGenerator() {
/**
* Are signatures incompatible with JVM spec allowed?
* Used by {@link LambdaTranslationContext#serializedLambdaDisambiguation()}.
*/
boolean allowIllegalSignatures;
L2MSignatureGenerator(boolean allowIllegalSignatures) {
super(types);
this.allowIllegalSignatures = allowIllegalSignatures;
}
@Override
protected void reportIllegalSignature(Type t) {
if (!allowIllegalSignatures) {
super.reportIllegalSignature(t);
}
}
@Override

@ -0,0 +1,66 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8210495
* @summary compiler crashes because of illegal signature in otherwise legal code
* @compile T8210495.java
*/
import java.awt.*;
import java.awt.event.ActionListener;
import java.util.List;
class T8210495 {
interface IFilter {
Component getComponent();
}
static class Filter implements IFilter {
@Override
public Component getComponent() {
return null;
}
}
public Component buildFilter(List<? extends Filter> l, Dialog dialog) {
Panel c = new Panel();
l.stream()
.map(f -> {
Button btn = (Button)f.getComponent();
btn.addActionListener((java.io.Serializable & ActionListener)evt -> {
applyFilter(f);
dialog.setVisible(false);
});
return btn;
})
.forEach(c::add);
return c;
}
private void applyFilter(IFilter f) { }
}