WALA bugfix patch v1.1.2 local changes
[eclipsethinslicer.git] / Svelte / WALA-bugfixes-200802191150-against-v1.1.2.patch
blob5e790349606cababe67e3038c79e82301727ef25
1 diff --git a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java
2 index 691baf7..05489ef 100644
3 --- a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java
4 +++ b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java
5 @@ -14,6 +14,7 @@
6 package com.ibm.wala.cast.java.test;
8 import java.io.File;
9 +import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.Collection;
12 import java.util.Iterator;
13 @@ -25,6 +26,7 @@ import junit.framework.Assert;
14 import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
15 import com.ibm.wala.cast.java.ipa.slicer.AstJavaSlicer;
16 import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
17 +import com.ibm.wala.cast.java.ssa.EnclosingObjectReference;
18 import com.ibm.wala.classLoader.IClass;
19 import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
20 import com.ibm.wala.core.tests.slicer.SlicerTest;
21 @@ -35,6 +37,8 @@ import com.ibm.wala.ipa.callgraph.CGNode;
22 import com.ibm.wala.ipa.callgraph.CallGraph;
23 import com.ibm.wala.ipa.callgraph.Entrypoint;
24 import com.ibm.wala.ipa.callgraph.impl.Util;
25 +import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
26 +import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
27 import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
28 import com.ibm.wala.ipa.cha.IClassHierarchy;
29 import com.ibm.wala.ipa.slicer.SDG;
30 @@ -374,6 +378,94 @@ public class JavaIRTests extends IRTests {
31 }), true);
34 + public void testInnerClassA() {
35 + Pair x = runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList<IRAssertion>(), true);
37 + // can't do an IRAssertion() -- we need the pointer analysis
39 + CallGraph cg = (CallGraph) x.fst;
40 + PointerAnalysis pa = (PointerAnalysis) x.snd;
42 + Iterator<CGNode> iter = cg.iterator();
43 + while ( iter.hasNext() ) {
44 + CGNode n = iter.next();
46 + // assume in the test we have one enclosing instruction for each of the methods here.
47 + String methodSigs[] = { "InnerClassA$AB.getA_X_from_AB()I",
48 + "InnerClassA$AB.getA_X_thru_AB()I",
49 + "InnerClassA$AB$ABSubA.getA_X()I",
50 + "InnerClassA$AB$ABA$ABAA.getABA_X()I",
51 + "InnerClassA$AB$ABA$ABAA.getA_X()I",
52 + "InnerClassA$AB$ABA$ABAB.getABA_X()I",
53 + "InnerClassA$AB$ABSubA$ABSubAA.getABA_X()I",
54 + "InnerClassA$AB$ABSubA$ABSubAA.getA_X()I", };
56 + // each type suffixed by ","
57 + String ikConcreteTypeStrings[ ]= {
58 + "LInnerClassA,",
59 + "LInnerClassA,",
60 + "LInnerClassA,",
61 + "LInnerClassA$AB$ABSubA,LInnerClassA$AB$ABA,",
62 + "LInnerClassA,",
63 + "LInnerClassA$AB$ABA,",
64 + "LInnerClassA$AB$ABSubA,",
65 + "LInnerClassA,",
66 + };
68 + Assert.assertTrue ( "Buggy test", methodSigs.length == ikConcreteTypeStrings.length );
69 + for ( int i = 0; i < methodSigs.length; i++ ) {
70 + if ( n.getMethod().getSignature().equals(methodSigs[i]) ) {
71 + // find enclosing instruction
72 + for ( SSAInstruction instr: n.getIR().getInstructions() ) {
73 + if ( instr instanceof EnclosingObjectReference ) {
74 + String allIks = "";
75 + for (InstanceKey ik: pa.getPointsToSet(new LocalPointerKey(n,instr.getDef())))
76 + allIks += ik.getConcreteType().getName() +",";
77 + System.out.printf("in method %s, got ik %s\n", methodSigs[i], allIks);
79 + Assert.assertTrue("assertion failed: expecting ik " + ikConcreteTypeStrings[i] + " in method " + methodSigs[i] + ", got " + allIks + "\n",
80 + allIks.equals(ikConcreteTypeStrings[i]));
82 + break;
83 + }
84 + }
85 + }
86 + }
87 + }
90 + }
92 + public void testInnerClassSuper() {
93 + Pair x = runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList<IRAssertion>(), true);
95 + // can't do an IRAssertion() -- we need the pointer analysis
97 + CallGraph cg = (CallGraph) x.fst;
98 + PointerAnalysis pa = (PointerAnalysis) x.snd;
100 + Iterator<CGNode> iter = cg.iterator();
101 + while ( iter.hasNext() ) {
102 + CGNode n = iter.next();
103 + if ( n.getMethod().getSignature().equals("LInnerClassSuper$SuperOuter.test()V") ) {
104 + // find enclosing instruction
105 + for ( SSAInstruction instr: n.getIR().getInstructions() ) {
106 + if ( instr instanceof EnclosingObjectReference ) {
107 + String allIks = "";
108 + for (InstanceKey ik: pa.getPointsToSet(new LocalPointerKey(n,instr.getDef())))
109 + allIks += ik.getConcreteType().getName() +",";
110 + Assert.assertTrue("assertion failed: expecting ik \"LSub,\" in method, got \"" + allIks + "\"\n",
111 + allIks.equals("LSub,"));
113 + break;
122 public void testLocalClass() {
123 runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), Arrays.asList(
125 diff --git a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.java b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.java
126 new file mode 100644
127 index 0000000..de1024f
128 --- /dev/null
129 +++ b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.java
130 @@ -0,0 +1,68 @@
131 +/******************************************************************************
132 + * Copyright (c) 2002 - 2006 IBM Corporation.
133 + * All rights reserved. This program and the accompanying materials
134 + * are made available under the terms of the Eclipse Public License v1.0
135 + * which accompanies this distribution, and is available at
136 + * http://www.eclipse.org/legal/epl-v10.html
138 + * Contributors:
139 + * IBM Corporation - initial API and implementation
140 + *****************************************************************************/
142 + * Created on Oct 21, 2005
143 + */
144 +package com.ibm.wala.cast.java.test;
146 +import java.io.File;
147 +import java.util.ArrayList;
149 +import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
150 +import com.ibm.wala.cast.java.client.impl.ZeroOneContainerCFABuilderFactory;
151 +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
152 +import com.ibm.wala.eclipse.util.EclipseProjectPath;
153 +import com.ibm.wala.ipa.callgraph.AnalysisCache;
154 +import com.ibm.wala.ipa.callgraph.AnalysisOptions;
155 +import com.ibm.wala.ipa.callgraph.AnalysisScope;
156 +import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
157 +import com.ibm.wala.ipa.callgraph.Entrypoint;
158 +import com.ibm.wala.ipa.callgraph.impl.Util;
159 +import com.ibm.wala.ipa.cha.IClassHierarchy;
161 +public class JavaOneContainerIRTests extends IRTests {
162 + public JavaOneContainerIRTests(String name) {
163 + super(name);
166 + protected JavaSourceAnalysisEngine getAnalysisEngine(final String[] mainClassDescriptors) {
167 + JavaSourceAnalysisEngine engine = new JavaSourceAnalysisEngine() {
168 + @Override
169 + protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha,
170 + AnalysisOptions options, AnalysisCache cache) {
171 + return new ZeroOneContainerCFABuilderFactory().make(options, cache, cha, scope, false);
174 + protected Iterable<Entrypoint> makeDefaultEntrypoints(AnalysisScope scope, IClassHierarchy cha) {
175 + return Util.makeMainEntrypoints(EclipseProjectPath.SOURCE_REF, cha, mainClassDescriptors);
177 + };
178 + engine.setExclusionsFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS);
179 + return engine;
182 + protected String singleInputForTest() {
183 + return getName().substring(4) + ".java";
186 + protected String singleInputForTestNoExt() {
187 + return getName().substring(4);
190 + protected String singlePkgInputForTest(String pkgName) {
191 + return pkgName + File.separator + getName().substring(4) + ".java";
194 + public void testInnerClassLexicalReads() {
195 + // throws UnimplementedError on failure (expecting ScopeMappingInstanceKeys but not generating them)
196 + runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList<IRAssertion>(), true);
199 diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java
200 new file mode 100644
201 index 0000000..f51541a
202 --- /dev/null
203 +++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java
204 @@ -0,0 +1,125 @@
205 +// other stranger test cases
207 +// combininations of:
208 +// o.new() form
209 +// function calls
210 +// getting enclosings from one AND multiple levels up
211 +// new Foo() which requires an enclosing instruction before (ie calling new Inner() from ReallyInner()
212 +// invariants and non-invariants (immediate 'new' in that function)
213 +// subclasses
215 +public class InnerClassA {
216 + int a_x;
218 + public static void main(String args[]) {
219 + // prints out 5 5 9 7 5 5 7 5 7 5
220 + InnerClassA a = new InnerClassA();
221 + AA aa = a.new AA();
222 + AB ab = aa.makeAB();
223 + a.a_x = 5;
225 + // tests
226 + int myx = ab.getA_X_from_AB();
227 + System.out.println(myx); // 5
228 + int myx2 = ab.getA_X_thru_AB();
229 + System.out.println(myx2); // 5
231 + aa.doSomeCrazyStuff();
234 + public int getA_X() {
235 + return a_x;
238 + class AA {
239 + int a2a_var;
241 + public AB makeAB() {
242 + return new AB();
245 + public void doSomeCrazyStuff() {
246 + AB ab = new AB();
247 + AB.ABSubA absuba = ab.new ABSubA();
248 + absuba.aba_x = 7;
249 + AB.ABA.ABAA abaa2 = ab.new ABA().new ABAA(); // just used to add ABA instance key in ABAA.getABA_X()
251 + AB.ABA aba = ab.new ABA();
252 + aba.aba_x = 9;
253 + AB.ABA.ABAB abab = aba.new ABAB();
254 + System.out.println(abab.getABA_X()); // 9
256 + AB.ABA.ABAA abaa = absuba.new ABAA();
257 + int myaba_x = abaa.getABA_X();
258 + int mya_x = abaa.getA_X();
259 + System.out.println(myaba_x); // 7
260 + System.out.println(mya_x); // 5
263 + doMoreWithABSubA(absuba);
266 + private void doMoreWithABSubA(InnerClassA.AB.ABSubA absuba) {
267 + System.out.println(absuba.getA_X()); // 5
269 + AB.ABSubA.ABSubAA absubaa = absuba.new ABSubAA();
270 + int myaba_x2 = absubaa.getABA_X();
271 + int mya_x2 = absubaa.getA_X();
272 + System.out.println(myaba_x2); // 7
273 + System.out.println(mya_x2); // 5
274 + // TODO Auto-generated method stub
276 + AB.ABA.ABAA abaa = absubaa.makeABAA();
277 + int myaba_x3 = abaa.getABA_X();
278 + int mya_x3 = abaa.getA_X();
279 + System.out.println(myaba_x3); // 7
280 + System.out.println(mya_x3); // 5
285 + class AB {
286 + public int getA_X_from_AB() {
287 + return a_x; // CHECK enclosing is an A
290 + public int getA_X_thru_AB() {
291 + return getA_X(); // CHECK enclosing is an A
294 + class ABA {
295 + int aba_x;
296 + class ABAA {
297 + int getABA_X() {
298 + return aba_x; // CHECK enclosing is an ABA or ABSubA
300 + int getA_X() {
301 + return a_x; // CHECK enclosing is an A
304 + class ABAB {
305 + int getABA_X() {
306 + return aba_x; // CHECK enclosing is an ABA
311 + class ABSubA extends ABA {
312 + class ABSubAA {
313 + int getABA_X() {
314 + return aba_x; // CHECK enclosing is an ABSubA
316 + int getA_X() {
317 + return a_x; // CHECK enclosing is an A
319 + ABA.ABAA makeABAA() {
320 + return new ABAA(); // this new instruction requires us to know that ABSubA is a subclass of ABA.
321 + // thus when we call getABA_X() on the result, it will need to find a EORK(this site,class ABA) -> THIS (of type ABSubAA)
324 + int getA_X() {
325 + return a_x; // CHECK enclosing is an A
330 diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java
331 new file mode 100644
332 index 0000000..6d15249
333 --- /dev/null
334 +++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java
335 @@ -0,0 +1,47 @@
336 +interface IntConstant {
337 + int getConstant();
340 +public class InnerClassLexicalReads {
342 + /*
343 + * CAst Instructions:
344 + * 2 v3 = new <Source,LInnerClassLexicalReads/makeIntConstant(I)LIntConstant;/<anonymous subtype of IntConstant>$9$9>@2[9:9] -> [13:3]
345 + * 3 invokespecial < Source, LInnerClassLexicalReads/makeIntConstant(I)LIntConstant;/<anonymous subtype of IntConstant>$9$9, <init>()V > v3 @3 exception:v5[9:9] -> [13:3]
346 + * 4 return v3 [9:2] -> [13:4]
347 + */
348 + public static IntConstant makeIntConstant(int x) {
349 + final int y = x * x;
350 + return new IntConstant() {
351 +// CAst CONSTRUCTOR Instructions:
352 +// 1 invokespecial < Source, Ljava/lang/Object, <init>()V > v1 @1 exception:v3[20:9] -> [32:3]
354 + /*
355 + * CAst Instructions:
356 + * 0 v2:com.ibm.wala.ssa.SymbolTable$1@16b18b6 = lexical:y@LInnerClassLexicalReads/makeIntConstant(I)LIntConstant;
357 + * 1 return v2:com.ibm.wala.ssa.SymbolTable$1@16b18b6[11:4] -> [11:13]
358 + */
359 + public int getConstant() {
360 + return y;
362 + };
366 + /*
367 + * CAst Instructions:
368 + * 1 v2:com.ibm.wala.ssa.SymbolTable$1@4272b2 = invokestatic < Source, LInnerClassLexicalReads, makeIntConstant(I)LIntConstant; > v3:#123 @1 exception:v4[17:19] -> [17:39]
369 + * 2 v7 = getstatic < Source, Ljava/lang/System, out, <Source,Ljava/io/PrintStream> >[18:2] -> [18:12]
370 + * 3 v8 = invokeinterface < Source, LIntConstant, getConstant()I > v2:com.ibm.wala.ssa.SymbolTable$1@4272b2 @3 exception:v9[18:21] -> [18:37]
371 + * 4 invokevirtual < Source, Ljava/io/PrintStream, println(I)V > v7,v8 @4 exception:v10[18:2] -> [18:38]
372 + */
373 + public static void main(String args[]) {
374 + InnerClassLexicalReads ignored = new InnerClassLexicalReads(); // call this just to make <init> reachable (test checks for unreachable methods)
375 + int foo = 5;
376 + int haha = foo * foo;
377 + IntConstant ic = makeIntConstant(haha);
378 + System.out.println(ic.getConstant());
379 + int x = ic.getConstant();
380 + System.out.println(x);
383 diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java
384 new file mode 100644
385 index 0000000..d61a986
386 --- /dev/null
387 +++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java
388 @@ -0,0 +1,19 @@
389 +public class InnerClassSuper {
390 + int x = 5;
391 + class SuperOuter {
392 + public void test() {
393 + System.out.println(x);
396 + public static void main(String args[]) {
397 + new Sub().new SubInner();
400 +class Sub extends InnerClassSuper {
401 + class SubInner {
402 + public SubInner() {
403 + InnerClassSuper.SuperOuter so = new InnerClassSuper.SuperOuter();
404 + so.test();
408 \ No newline at end of file
409 diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java
410 index 94993c1..b94db65 100644
411 --- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java
412 +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java
413 @@ -16,6 +16,7 @@ import com.ibm.wala.cast.java.analysis.typeInference.AstJavaTypeInference;
414 import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.JavaClass;
415 import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor;
416 import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
417 +import com.ibm.wala.cast.java.ssa.AstJavaNewEnclosingInstruction;
418 import com.ibm.wala.cast.java.ssa.EnclosingObjectReference;
419 import com.ibm.wala.classLoader.IClass;
420 import com.ibm.wala.fixedpoint.impl.UnaryOperator;
421 @@ -182,6 +183,14 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
422 super(builder, node);
425 + /**
426 + * For each of objKey's instance keys ik, adds the constraint lvalKey = EORK(ik,cls),
427 + * where EORK(ik,cls) will be made equivalent to the actual enclosing class by
428 + * the handleNew() function below.
429 + * @param lvalKey
430 + * @param cls
431 + * @param objKey
432 + */
433 private void handleEnclosingObject(final PointerKey lvalKey, final IClass cls, final PointerKey objKey) {
434 SymbolTable symtab = ir.getSymbolTable();
435 int objVal;
436 @@ -246,12 +255,33 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
437 if (iKey != null) {
438 IClass klass = iKey.getConcreteType();
440 + // in the case of a AstJavaNewEnclosingInstruction (a new instruction like outer.new Bla()),
441 + // we may need to record the instance keys if the pointer key outer is invariant (and thus implicit)
442 + InstanceKey enclosingInvariantKeys[] = null;
444 if (klass instanceof JavaClass) {
445 - IClass enclosingClass = ((JavaClass) klass).getEnclosingClass();
446 + IClass enclosingClass = ((JavaClass) klass).getEnclosingClass(); // the immediate enclosing class.
447 if (enclosingClass != null) {
448 IClass currentCls = node.getMethod().getDeclaringClass();
449 - PointerKey objKey = getPointerKeyForLocal(1);
450 - boolean needIndirection = false;
451 + PointerKey objKey;
453 + if ( instruction instanceof AstJavaNewEnclosingInstruction ) {
456 + int enclosingVal = ((AstJavaNewEnclosingInstruction) instruction).getEnclosing();
457 + SymbolTable symtab = ir.getSymbolTable();
459 + // pk 'outer' is invariant, which means it's implicit, so can't add a constraint with the pointer key.
460 + // we should just add constraints directly to the instance keys (below)
461 + if ( contentsAreInvariant(symtab, du, enclosingVal) )
462 + enclosingInvariantKeys = getInvariantContents(enclosingVal);
464 + // what happens if objKey is implicit but the contents aren't invariant?! (it this possible?) big trouble!
466 + objKey = getPointerKeyForLocal(enclosingVal);
468 + else
469 + objKey = getPointerKeyForLocal(1);
471 Trace.println("class is " + klass + ", enclosing is " + enclosingClass + ", method is " + node.getMethod());
473 @@ -259,31 +289,30 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
474 return;
477 - while (!getClassHierarchy().isSubclassOf(currentCls, enclosingClass)) {
478 - Assertions._assert(currentCls instanceof JavaClass);
479 + currentCls = enclosingClass;
481 + PointerKey x = new EnclosingObjectReferenceKey(iKey, currentCls);
482 + if ( enclosingInvariantKeys != null )
483 + for ( InstanceKey obj: enclosingInvariantKeys )
484 + system.newConstraint(x, obj);
485 + else
486 + system.newConstraint(x, assignOperator, objKey);
488 + // If the immediate inclosing class is not a top-level class, we must make EORKs for all enclosing classes up to the top level.
489 + // for instance, if we have "D d = c.new D()", and c is of type A$B$C, methods in D may reference variables and functions from
490 + // A, B, and C. Therefore we must also make the links from EORK(allocsite of d,enc class B) and EORK(allocsite of d,en class A).
491 + // We do this by getting the enclosing class of C and making a link from EORK(d,B) -> EORK(c,B), etc.
492 + currentCls = ((JavaClass) currentCls).getEnclosingClass();
493 + while (currentCls != null) {
494 + x = new EnclosingObjectReferenceKey(iKey, currentCls); // make EORK(d,B), EORK(d,A), etc.
495 + handleEnclosingObject(x, currentCls, objKey);
496 + // objKey is the pointer key representing the immediate inner class.
497 + // handleEnclosingObject finds x's instance keys and for each one "ik" links x to EORK(ik,currentCls)
498 + // thus, for currentCls=B, it will find the allocation site of c and make a link from EORK(d,B) to EORK(c,B)
500 currentCls = ((JavaClass) currentCls).getEnclosingClass();
501 - needIndirection = true;
504 - while (enclosingClass != null) {
505 - PointerKey x = new EnclosingObjectReferenceKey(iKey, enclosingClass);
506 - if (needIndirection) {
507 - handleEnclosingObject(x, currentCls, objKey);
508 - Trace.println("at " + instruction + ": adding " + iKey + ", " + enclosingClass + " <-- " + objKey + ", "
509 - + currentCls);
510 - } else {
511 - system.newConstraint(x, assignOperator, objKey);
512 - Trace.println("at " + instruction + ": adding " + iKey + ", " + enclosingClass + " <-- " + objKey);
515 - if (enclosingClass instanceof JavaClass) {
516 - needIndirection = true;
517 - enclosingClass = ((JavaClass) enclosingClass).getEnclosingClass();
518 - currentCls = ((JavaClass) currentCls).getEnclosingClass();
519 - } else {
520 - break;
527 diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java
528 index cf12e87..d6d9b5e 100644
529 --- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java
530 +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java
531 @@ -62,9 +62,9 @@ public class AstJavaZeroOneContainerCFABuilder extends AstJavaCFABuilder {
532 setContextInterpreter(contextInterpreter);
534 ZeroXInstanceKeys zik = makeInstanceKeys(cha, options, contextInterpreter);
535 - setInstanceKeys(zik);
536 + setInstanceKeys(new JavaScopeMappingInstanceKeys(cha, this, zik));
538 - ContextSelector CCS = makeContainerContextSelector(cha,(ZeroXInstanceKeys) getInstanceKeys());
539 + ContextSelector CCS = makeContainerContextSelector(cha,zik);
540 DelegatingContextSelector DCS = new DelegatingContextSelector(CCS, contextSelector);
541 setContextSelector(DCS);
543 diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java
544 new file mode 100644
545 index 0000000..45718e5
546 --- /dev/null
547 +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java
548 @@ -0,0 +1,25 @@
549 +package com.ibm.wala.cast.java.ssa;
551 +import com.ibm.wala.classLoader.NewSiteReference;
552 +import com.ibm.wala.ssa.SSANewInstruction;
554 +// A new instruction with an explicit outer class, i.e. "Inner inner = outer.new Inner();"
555 +public class AstJavaNewEnclosingInstruction extends SSANewInstruction {
557 + int enclosing;
559 + public AstJavaNewEnclosingInstruction(int result, NewSiteReference site, int enclosing) throws IllegalArgumentException {
560 + super(result, site);
561 + this.enclosing = enclosing;
564 + public int getEnclosing() {
565 + return this.enclosing;
568 + public String toString() {
569 + return super.toString() + " ENCLOSING v" + enclosing;
574 diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java
575 index 9d302ae..774eaaf 100644
576 --- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java
577 +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java
578 @@ -19,6 +19,7 @@ import java.util.Iterator;
579 import com.ibm.wala.cast.ir.translator.AstTranslator;
580 import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
581 import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
582 +import com.ibm.wala.cast.java.ssa.AstJavaNewEnclosingInstruction;
583 import com.ibm.wala.cast.java.ssa.EnclosingObjectReference;
584 import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation;
585 import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
586 @@ -156,11 +157,14 @@ public class JavaCAst2IRTranslator extends AstTranslator {
587 NewSiteReference site =
588 NewSiteReference.make(context.cfg().getCurrentInstruction(), typeRef);
590 - context.cfg().addInstruction(
591 - (arguments == null)?
592 - SSAInstructionFactory.NewInstruction(result, site):
593 - new SSANewInstruction(result, site, arguments));
595 + if ( newNode.getKind() == CAstNode.NEW_ENCLOSING ) {
596 + context.cfg().addInstruction ( new AstJavaNewEnclosingInstruction(result, site, arguments[0]));
597 + } else {
598 + context.cfg().addInstruction(
599 + (arguments == null)?
600 + SSAInstructionFactory.NewInstruction(result, site):
601 + new SSANewInstruction(result, site, arguments));
603 processExceptions(newNode, context);
606 diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java
607 index f9f1222..17910ce 100644
608 --- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java
609 +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java
610 @@ -746,7 +746,16 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
611 String tmpName = "ctor temp"; // this name is an illegal Java
612 // identifier
614 - CAstNode newNode = makeNode(wc, fFactory, n, CAstNode.NEW, fFactory.makeConstant(newTypeRef));
615 + // new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in JavaCAst2IRTranslator.doNewObject
616 + CAstNode newNode;
617 + Expr enclosing = n.qualifier();
618 + if ( enclosing != null ) {
619 + CAstNode encNode = walkNodes(enclosing, wc);
620 + newNode = makeNode(wc, fFactory, n, CAstNode.NEW_ENCLOSING, fFactory.makeConstant(newTypeRef), encNode);
622 + else
623 + newNode = makeNode(wc, fFactory, n, CAstNode.NEW, fFactory.makeConstant(newTypeRef));
624 + // end enclosing new stuff
626 if (n.body() != null)
627 wc.addScopedEntity(newNode, anonClass);
628 diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java
629 index 381a8cf..711617c 100644
630 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java
631 +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java
632 @@ -128,7 +128,7 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
633 return base.getConcreteType();
636 - CGNode getDefiningNode(String definer) {
637 + public CGNode getDefiningNode(String definer) {
638 return map.getDefiningNode(definer);
641 diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java
642 index 1c41365..ec8cd1e 100644
643 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java
644 +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java
645 @@ -2610,8 +2610,8 @@ public abstract class AstTranslator extends CAstVisitor
646 int result = getValue(n);
647 CAstNode l = n.getChild(1);
648 CAstNode r = n.getChild(2);
649 - Assertions._assert(getValue(r) != -1, CAstPrinter.print(n));
650 - Assertions._assert(getValue(l) != -1, CAstPrinter.print(n));
651 +// Assertions._assert(getValue(r) != -1, CAstPrinter.print(n));
652 +// Assertions._assert(getValue(l) != -1, CAstPrinter.print(n));
654 boolean mayBeInteger = handleBinaryOpThrow(n, n.getChild(0), context);
656 diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java
657 index 18bf26f..b420421 100644
658 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java
659 +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java
660 @@ -155,6 +155,9 @@ public interface CAstNode {
661 public static final int TYPE_LITERAL_EXPR = 127;
662 public static final int IS_DEFINED_EXPR = 128;
664 + // new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in JavaCAst2IRTranslator.doNewObject
665 + public static final int NEW_ENCLOSING = 129;
667 // explicit lexical scopes
668 public static final int LOCAL_SCOPE = 200;
670 diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java
671 index 44f7055..e3ad94f 100644
672 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java
673 +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java
674 @@ -554,6 +554,7 @@ public abstract class CAstVisitor {
675 break;
678 + case CAstNode.NEW_ENCLOSING:
679 case CAstNode.NEW: {
680 if (visitor.visitNew(n, context, visitor))
681 break;
682 diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java
683 index 05ef170..ef226b7 100644
684 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java
685 +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java
686 @@ -71,6 +71,7 @@ public class CAstPrinter {
687 case CAstNode.IF_EXPR: return "IF_EXPR";
688 case CAstNode.ANDOR_EXPR: return "ANDOR_EXPR";
689 case CAstNode.NEW: return "NEW";
690 + case CAstNode.NEW_ENCLOSING: return "NEW_ENCLOSING";
691 case CAstNode.OBJECT_LITERAL: return "LITERAL";
692 case CAstNode.VAR: return "VAR";
693 case CAstNode.OBJECT_REF: return "OBJECT_REF";