mirror of
https://github.com/eclipse-aspectj/aspectj.git
synced 2024-09-13 15:45:38 +02:00
based on patch contributed by Andy Clement Generalizes the patch with a method org.aspectj.weaver.bcel.Utility.copyInstruction that works-around the bug in Select.copy(). Changed all calls to Instruction.copy() to use this new method, would be nice to add the rule: * declare error: * call(* Instruction.copy()) && within(org.aspectj.weaver) * && !withincode(* Utility.copyInstruction(Instruction)): * "use Utility.copyInstruction to work-around bug in Select.copy()";
This commit is contained in:
parent
cd9946a959
commit
13b319a40f
@ -6408,4 +6408,16 @@
|
||||
<message kind="error" line="13"/>
|
||||
</compile>
|
||||
</ajc-test>
|
||||
|
||||
<ajc-test dir="bugs" pr="39479"
|
||||
title="NPE in bcel.LazyMethodGen when delegating from one ctor to a second that includes a switch">
|
||||
<compile files="NewSwitch.java"/>
|
||||
<run class="NewSwitch"/>
|
||||
</ajc-test>
|
||||
|
||||
<ajc-test dir="bugs" pr="40109"
|
||||
title="switch statement in aspects crashes weaving">
|
||||
<compile files="SwitchInAround.java"/>
|
||||
<run class="SwitchInAround"/>
|
||||
</ajc-test>
|
||||
</suite>
|
||||
|
@ -9,11 +9,5 @@
|
||||
<compile files="lib.jar,TestAspect.aj,Test.java"/>
|
||||
<run class="Test"/>
|
||||
</ajc-test>
|
||||
|
||||
<ajc-test dir="bugs" pr="39479"
|
||||
title="NPE in bcel.LazyMethodGen when delegating from one ctor to a second that includes a switch">
|
||||
<compile files="NewSwitch.java"/>
|
||||
<run class="NewSwitch"/>
|
||||
</ajc-test>
|
||||
|
||||
</suite>
|
||||
|
27
tests/bugs/SwitchInAround.java
Normal file
27
tests/bugs/SwitchInAround.java
Normal file
@ -0,0 +1,27 @@
|
||||
import org.aspectj.testing.Tester;
|
||||
|
||||
public class SwitchInAround {
|
||||
public static void main(String[] args) {
|
||||
SwitchInAround o = new SwitchInAround();
|
||||
Tester.checkEqual(o.doit(1), "1");
|
||||
Tester.checkEqual(o.doit(2), "2");
|
||||
Tester.checkEqual(o.doit(3), "default");
|
||||
}
|
||||
|
||||
public String doit(int i) {
|
||||
return "doit";
|
||||
}
|
||||
}
|
||||
|
||||
privileged aspect A {
|
||||
String around(int index): args(index) && call(String doit(int)) {
|
||||
switch(index) {
|
||||
case 1:
|
||||
return "1";
|
||||
case 2:
|
||||
return "2";
|
||||
default:
|
||||
return "default";
|
||||
}
|
||||
}
|
||||
}
|
@ -443,7 +443,7 @@ class BcelClassWeaver implements IClassWeaver {
|
||||
src != null;
|
||||
src = src.getNext())
|
||||
{
|
||||
Instruction fresh = src.getInstruction().copy();
|
||||
Instruction fresh = Utility.copyInstruction(src.getInstruction());
|
||||
InstructionHandle dest;
|
||||
if (fresh instanceof CPInstruction) {
|
||||
// need to reset index to go to new constant pool. This is totally
|
||||
|
@ -953,7 +953,7 @@ public class BcelShadow extends Shadow {
|
||||
for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
|
||||
if (ih.getInstruction() instanceof ReturnInstruction) {
|
||||
returns.add(ih);
|
||||
ret = ih.getInstruction().copy();
|
||||
ret = Utility.copyInstruction(ih.getInstruction());
|
||||
}
|
||||
}
|
||||
InstructionList retList;
|
||||
|
@ -728,7 +728,7 @@ public final class LazyMethodGen {
|
||||
continue;
|
||||
}
|
||||
Instruction i = ih.getInstruction();
|
||||
Instruction c = i.copy(); // Use clone for shallow copy
|
||||
Instruction c = Utility.copyInstruction(i);
|
||||
|
||||
if (c instanceof BranchInstruction)
|
||||
map.put(ih, fresh.append((BranchInstruction) c));
|
||||
|
@ -71,7 +71,7 @@ final class ShadowRange extends Range {
|
||||
for (InstructionHandle oldIh = start.getNext(); oldIh != end; oldIh = oldIh.getNext()) {
|
||||
// first we copy the instruction itself.
|
||||
Instruction oldI = oldIh.getInstruction();
|
||||
Instruction freshI = (oldI == RANGEINSTRUCTION) ? oldI : oldI.copy();
|
||||
Instruction freshI = (oldI == RANGEINSTRUCTION) ? oldI : Utility.copyInstruction(oldI);
|
||||
|
||||
// Now we add it to the new instruction list.
|
||||
InstructionHandle freshIh;
|
||||
|
@ -21,6 +21,7 @@ import org.apache.bcel.Constants;
|
||||
import org.apache.bcel.classfile.ClassParser;
|
||||
import org.apache.bcel.classfile.JavaClass;
|
||||
import org.apache.bcel.classfile.Method;
|
||||
import org.apache.bcel.generic.ArrayType;
|
||||
import org.apache.bcel.generic.BIPUSH;
|
||||
import org.apache.bcel.generic.BasicType;
|
||||
import org.apache.bcel.generic.BranchInstruction;
|
||||
@ -34,9 +35,10 @@ import org.apache.bcel.generic.InstructionList;
|
||||
import org.apache.bcel.generic.InstructionTargeter;
|
||||
import org.apache.bcel.generic.LDC;
|
||||
import org.apache.bcel.generic.ObjectType;
|
||||
import org.apache.bcel.generic.ArrayType;
|
||||
import org.apache.bcel.generic.ReferenceType;
|
||||
import org.apache.bcel.generic.SIPUSH;
|
||||
import org.apache.bcel.generic.SWITCH;
|
||||
import org.apache.bcel.generic.Select;
|
||||
import org.apache.bcel.generic.TargetLostException;
|
||||
import org.apache.bcel.generic.Type;
|
||||
import org.aspectj.weaver.BCException;
|
||||
@ -419,6 +421,41 @@ public class Utility {
|
||||
throw new BCException("this really can't happen");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix for Bugzilla #39479, #40109 patch contributed by Andy Clement
|
||||
*
|
||||
* Need to manually copy Select instructions - if we rely on the the 'fresh' object
|
||||
* created by copy(), the InstructionHandle array 'targets' inside the Select
|
||||
* object will not have been deep copied, so modifying targets in fresh will modify
|
||||
* the original Select - not what we want ! (It is a bug in BCEL to do with cloning
|
||||
* Select objects).
|
||||
*
|
||||
* <pre>
|
||||
* declare error:
|
||||
* call(* Instruction.copy()) && within(org.aspectj.weaver)
|
||||
* && !withincode(* Utility.copyInstruction(Instruction)):
|
||||
* "use Utility.copyInstruction to work-around bug in Select.copy()";
|
||||
* </pre>
|
||||
*/
|
||||
public static Instruction copyInstruction(Instruction i) {
|
||||
if (i instanceof Select) {
|
||||
Select freshSelect = (Select)i;
|
||||
|
||||
// Create a new targets array that looks just like the existing one
|
||||
InstructionHandle[] targets = new InstructionHandle[freshSelect.getTargets().length];
|
||||
for (int ii = 0; ii < targets.length; ii++) {
|
||||
targets[ii] = freshSelect.getTargets()[ii];
|
||||
}
|
||||
|
||||
// Create a new select statement with the new targets array
|
||||
SWITCH switchStatement = new SWITCH(freshSelect.getMatchs(),targets,freshSelect.getTarget());
|
||||
return (Select)switchStatement.getInstruction();
|
||||
} else {
|
||||
return i.copy(); // Use clone for shallow copy...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** returns -1 if no source line attribute */
|
||||
// this naive version overruns the JVM stack size, if only Java understood tail recursion...
|
||||
|
Loading…
Reference in New Issue
Block a user