Fix bytecode generation for SpEL OpPlus

Without this change the plus operator would fail to
include a CHECKCAST in generated bytecode when it
was compiled in cases where one of the operands
has a runtime type of String but a statically
declared type that was not String (i.e. Object).

Issue: SPR-12426
master
Andy Clement 10 years ago
parent aa892d97e0
commit 94ee763bc8
  1. 3
      spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java
  2. 29
      spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java

@ -206,6 +206,9 @@ public class OpPlus extends Operator {
else { else {
cf.enterCompilationScope(); cf.enterCompilationScope();
operand.generateCode(mv,cf); operand.generateCode(mv,cf);
if (cf.lastDescriptor() != "Ljava/lang/String") {
mv.visitTypeInsn(CHECKCAST, "java/lang/String");
}
cf.exitCompilationScope(); cf.exitCompilationScope();
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
} }

@ -1683,12 +1683,41 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
expression = parse("'hello' + 3 + ' spring'"); expression = parse("'hello' + 3 + ' spring'");
assertEquals("hello3 spring",expression.getValue(new Greeter())); assertEquals("hello3 spring",expression.getValue(new Greeter()));
assertCantCompile(expression); assertCantCompile(expression);
expression = parse("object + 'a'");
assertEquals("objecta",expression.getValue(new Greeter()));
assertCanCompile(expression);
assertEquals("objecta",expression.getValue(new Greeter()));
expression = parse("'a'+object");
assertEquals("aobject",expression.getValue(new Greeter()));
assertCanCompile(expression);
assertEquals("aobject",expression.getValue(new Greeter()));
expression = parse("'a'+object+'a'");
assertEquals("aobjecta",expression.getValue(new Greeter()));
assertCanCompile(expression);
assertEquals("aobjecta",expression.getValue(new Greeter()));
expression = parse("object+'a'+object");
assertEquals("objectaobject",expression.getValue(new Greeter()));
assertCanCompile(expression);
assertEquals("objectaobject",expression.getValue(new Greeter()));
expression = parse("object+object");
assertEquals("objectobject",expression.getValue(new Greeter()));
assertCanCompile(expression);
assertEquals("objectobject",expression.getValue(new Greeter()));
} }
public static class Greeter { public static class Greeter {
public String getWorld() { public String getWorld() {
return "world"; return "world";
} }
public Object getObject() {
return "object";
}
} }
@Test @Test

Loading…
Cancel
Save