Bug 87525 - privilege error
Summary: privilege error
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2.1   Edit
Hardware: PC Windows XP
: P5 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-09 12:16 EST by Dapeng Gao CLA
Modified: 2007-10-23 06:40 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dapeng Gao CLA 2005-03-09 12:16:06 EST
public class Test {
	final static private int constant = 1;

	public static void main(String[] args) {
		T();
	}
	
	public static void T(){}
}


public privileged aspect TestAspect {
	
	before():
		call(public void Test.T()){
		switch(1){
		   case Test.constant:
		   	  System.out.println("hello");
		   default:
		 
		}
	}
}

When compiling the above code, I will get "case expression must be constant 
expressions" error at the case statement of the switch block. The aspect class 
is already declared as privileged, so it should be able to access the static 
private field, constant, of the Test class


Dapeng Gao
Comment 1 Matt Chapman CLA 2005-03-10 06:21:52 EST
I suspect it's due to generated accessor methods. Passing over to AspectJ
component as it's a language issue.
Comment 2 Adrian Colyer CLA 2005-03-23 09:56:04 EST
for investigation in aj5m3...
Comment 3 Andrew J Huff CLA 2005-05-31 10:00:51 EDT
class A {

  // only happens when the below line is non-static, or private static
  final int c = 1;

  void a() {
    switch(1){
      case c: // this is fine
    }
  }

}


aspect B {

  before(A anA):execution(* a()) && this(anA){   
      switch(1){
        case anA.c: // "case expressions must be constant expressions"
      }
    }

}

// hypothesis:
// problem is that 'get' methods are made so that aspect B
// can get the value of things in A.
// but this doesn't work here,
// because the 'get' method doesn't count as a constant expression
// (it could have side effects, etc)
//
// possible solution:
// if the thing in class A is a constant expression
// make a 'get' constant expression for it instead...
// like "final int getC = c"
// instead of "final int getC(){return c}
Comment 4 Andrew Clement CLA 2005-08-24 03:53:59 EDT
not going to get to this for M3
Comment 5 Andrew Clement CLA 2005-11-09 03:47:31 EST
The discussion in the bug is correct.  In order for the non-public field to be
accessible to the advice in the aspect, we have to create an accessor method. 
(That's how privileged works).  We do not hack the visibility of the field so
that the aspect can see it.

References to the non-public field from outside of the type are converted to
references to the accessor method.  This is invalid in a switch statement so you
get the compile error.

It is not a trivial piece of work to modify the accessor infrastructure to
behave differently for final fields - and given the workaround is:

privileged aspect TestAspect {
  before(): call(public void Test.T()){
    if (1==Test.constant) {
      System.out.println("hello");
    }
  }
}

I'm proposing we dont do this for 1.5.0 (this problem has existed since
AspectJ1.2 and earlier, its not new).  For 1.5 I could possibly put out a better
error message for this situation.
Comment 6 Andrew Clement CLA 2005-11-23 07:35:53 EST
new message added that is a little more intuitive.  moving this bug out of 1.5.0 now...