]> source.dussan.org Git - aspectj.git/commitdiff
Fix for Bugzilla Bug 65319
authoraclement <aclement>
Tue, 10 Aug 2004 16:22:01 +0000 (16:22 +0000)
committeraclement <aclement>
Tue, 10 Aug 2004 16:22:01 +0000 (16:22 +0000)
   ajc crashes when compiling the following program (binding this() and target())

tests/bugs/oxford/PR65319.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java
tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
weaver/src/org/aspectj/weaver/patterns/ExposedState.java
weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java

diff --git a/tests/bugs/oxford/PR65319.java b/tests/bugs/oxford/PR65319.java
new file mode 100644 (file)
index 0000000..2a00b9a
--- /dev/null
@@ -0,0 +1,30 @@
+class Test
+{  
+       public static void main(String args[]) {                
+               new Test().method();
+       }
+       public void method() {
+               new Test2().method2();
+       }
+       
+       public void method3() {
+               new Test2().method3(new Test());
+       }
+       
+       public void method4(Test t) {
+               new Test().method4(new Test());
+       }
+}
+class Test2 {
+       public void method2() {}
+       public void method3(Test t) {}
+}
+aspect Plain {
+       before(Test x):  call(void *.* (..)) && (target(x) || this(x)) {}
+
+       before(Test x):  call(void *.* (..)) && (this(x) || target(x)){}
+       
+       before(Test x):  call(void *.*(..)) && (this(x) || args(x)) {}
+       
+       before(Test x):  call(void *.*(..)) && (args(x) || target(x)) {}
+}
\ No newline at end of file
index 5a3c6d496f97d478ccc005ae912a085286a5de49..e32a91e37e5502b6490bea29fe8f46f230ec4242 100644 (file)
@@ -10,7 +10,9 @@
 package org.aspectj.systemtest.ajc121;
 
 import java.io.File;
+
 import junit.framework.Test;
+
 import org.aspectj.testing.XMLBasedAjcTestCase;
 
 public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
@@ -139,5 +141,10 @@ public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
   public void test025_proceedInAround3() {
       runTest("proceed used as method name in around advice (3)");
   }
+  
+  public void test026_bindingThisAndTargetToTheSameFormal() {
+       runTest("ajc crashes when compiling the following program (binding this() and target())");
+  }
+
 }
 
index 37ac4da2dbed8278524b98028905cc88649cdb14..579adf58d6430f199007d89a996654b831b5667d 100644 (file)
        title="proceed used as method name in around advice (3)">
        <compile files="Proceeding3.aj"/>
        <run class="Proceeding3"/>
-       </ajc-test>
\ No newline at end of file
+       </ajc-test>
+
+    <ajc-test dir="bugs/oxford" pr="65319"
+               title="ajc crashes when compiling the following program (binding this() and target())">
+               <compile files="PR65319.java">
+                       <message kind="error" line="7" text="Cannot use target() to match at this"/>
+                       <message kind="error" line="7" text="Cannot use this() to match at this"/>
+                       <message kind="error" line="11" text="Cannot use target() to match at this"/>
+                       <message kind="error" line="11" text="Cannot use this() to match at this"/>
+                       <message kind="error" line="11" text="Ambiguous binding of type Test"/>
+                       <message kind="error" line="15" text="Cannot use target() to match at this"/>
+                       <message kind="error" line="15" text="Cannot use this() to match at this"/>
+                       <message kind="error" line="15" text="Ambiguous binding of type Test"/>
+               </compile>
+       </ajc-test>
index e35128a622154ac48beae3e5652ea8a9aff7a171..310e9466a941dd3b97b1bc30fa7109c2ff99c71f 100644 (file)
@@ -291,6 +291,7 @@ public class BcelAdvice extends Advice {
                                BcelRenderer.renderExpr(fact, world, exposedState.getAspectInstance()));
                }
         for (int i = 0, len = exposedState.size(); i < len; i++) {
+               if (exposedState.isErroneousVar(i)) continue; // Erroneous vars have already had error msgs reported!
             BcelVar v = (BcelVar) exposedState.get(i);
             if (v == null) continue;
             TypeX desiredTy = getSignature().getParameterTypes()[i];
index 6cbe6ce5654ba5698630dcb633d05977363b9773..6b65417580027879ca685a5f6cdce2d940bbe8fa 100644 (file)
@@ -173,9 +173,11 @@ public class ArgsPointcut extends NameBindingPointcut {
                                ISourceLocation isl = getSourceLocation();
                                Message errorMessage = new Message(
                     "Ambiguous binding of type "+type.getExactType().toString()+
-                    " using args(..) at this line.  Use one args(..) per matched join point,"+"" +\r                    " see secondary source location for location of extraneous args(..)",
+                    " using args(..) at this line - formal is already bound"+
+                    ".  See secondary source location for location of args(..)",
                                        shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()});
                                shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
+                               state.setErroneousVar(btp.getFormalIndex());
                          }
                        }
                        ret = Test.makeAnd(ret,
index 063b5608e614b124c42752b709598d083c6a3259..f092ad54dcd814c2fae0061606cc95e832ae7f43 100644 (file)
@@ -21,11 +21,13 @@ import org.aspectj.weaver.ast.Var;
 
 public class ExposedState {
        public Var[] vars;
+       private boolean[] erroneousVars;
        private Expr aspectInstance;
 
        public ExposedState(int size) {
                super();
                vars = new Var[size];
+               erroneousVars = new boolean[size];
        }
 
        public ExposedState(Member signature) {
@@ -35,7 +37,11 @@ public class ExposedState {
 
        public void set(int i, Var var) {
                //XXX add sanity checks
-               // Check (1) added to call of set(), verifies we aren't binding twice to the same formal
+               // Some checks added in ArgsPointcut and ThisOrTargetPointcut
+//             if (vars[i]!=null) {
+//                     if (!var.getType().equals(vars[i].getType())) 
+//                       throw new RuntimeException("Shouldn't allow a slot to change type! Currently="+var.getType()+"   New="+vars[i].getType());
+//             }
                vars[i] = var;
        }
     public Var get(int i) {
@@ -56,4 +62,14 @@ public class ExposedState {
        public String toString() {
                return "ExposedState(" + Arrays.asList(vars) + ", " + aspectInstance + ")";
        }
+
+       // Set to true if we have reported an error message against it,
+       // prevents us blowing up in later code gen.
+       public void setErroneousVar(int formalIndex) {
+               erroneousVars[formalIndex]=true;
+       }
+       
+       public boolean isErroneousVar(int formalIndex) {
+               return erroneousVars[formalIndex];
+       }
 }
index 37d8ac68c91d6f1da7f21991aefb20cbae95e041..31fe527e377ca644978b24804f4d52c0ded57b55 100644 (file)
@@ -18,6 +18,8 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
@@ -123,7 +125,24 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
                
                if (type == TypePattern.ANY) return Literal.TRUE;
                
-               Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar();
+               Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar(); 
+
+               if (type instanceof BindingTypePattern) {
+                 BindingTypePattern btp = (BindingTypePattern)type;
+                 // Check if we have already bound something to this formal
+                 if (state.get(btp.getFormalIndex())!=null) {
+                       ISourceLocation pcdSloc = getSourceLocation(); 
+                       ISourceLocation shadowSloc = shadow.getSourceLocation();
+                       Message errorMessage = new Message(
+                               "Cannot use "+(isThis?"this()":"target()")+" to match at this location and bind a formal to type '"+var.getType()+
+                               "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+
+                               ".  The secondary source location points to the problematic "+(isThis?"this()":"target()")+".",
+                               shadowSloc,true,new ISourceLocation[]{pcdSloc}); 
+                       shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
+                       state.setErroneousVar(btp.getFormalIndex());
+                       //return null;
+                 }
+               }
                return exposeStateForVar(var, type, state, shadow.getIWorld());
        }