blob: be763c83c0377eba12757c5f5dbb3ff6f602b30c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.eclipse.jdt.core.tests.compiler.regression.NullReferenceImplTests.State;
import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
public class NullReferenceImplTransformations {
public static final Transformation
markAsComparedEqualToNonNull =
// markAsComparedEqualToNonNull DEFINITION START
// start => prot. non null
// prot. non null => prot. non null
// prot. null => prot. non null
// pot. unknown => pot. nn & prot. nn
// pot. non null => pot. nn & prot. nn
// pot. nn & prot. nn => pot. nn & prot. nn
// pot. nn & pot. un => pot. nn & prot. nn
// pot. null => prot. non null
// pot. n & prot. n => prot. non null
// pot. n & pot. un => pot. nn & prot. nn
// pot. n & pot. nn => pot. nn & prot. nn
// def. unknown => def. non null
// def. non null => def. non null
// def. null => prot. non null
// markAsComparedEqualToNonNull DEFINITION END
new TwoDimensionalTransformation("markAsComparedEqualToNonNull",
new byte[][] {
// markAsComparedEqualToNonNull INITIALIZER START
{0x00,0x3C},
{0x04,0x2C},
{0x08,0x2C},
{0x0C,0x2C},
{0x10,0x3C},
{0x14,0x2C},
{0x18,0x2C},
{0x24,0x28},
{0x28,0x28},
{0x2C,0x2C},
{0x30,0x3C},
{0x34,0x3C},
{0x38,0x3C},
{0x3C,0x3C},
// markAsComparedEqualToNonNull INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input,
TestLocalVariableBinding local) {
UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy();
result.markAsComparedEqualToNonNull(local);
return result;
}
},
markAsComparedEqualToNull =
// markAsComparedEqualToNull DEFINITION START
// start => prot. null
// prot. non null => prot. null
// prot. null => prot. null
// pot. unknown => pot. n & prot. n
// pot. non null => prot. null
// pot. nn & prot. nn => prot. null
// pot. nn & pot. un => pot. n & prot. n
// pot. null => pot. n & prot. n
// pot. n & prot. n => pot. n & prot. n
// pot. n & pot. un => pot. n & prot. n
// pot. n & pot. nn => pot. n & prot. n
// def. unknown => def. null
// def. non null => prot. null
// def. null => def. null
// markAsComparedEqualToNull DEFINITION END
new TwoDimensionalTransformation("markAsComparedEqualToNull",
new byte[][] {
// markAsComparedEqualToNull INITIALIZER START
{0x00,0x38},
{0x04,0x34},
{0x08,0x38},
{0x0C,0x34},
{0x10,0x34},
{0x14,0x34},
{0x18,0x34},
{0x24,0x30},
{0x28,0x38},
{0x2C,0x38},
{0x30,0x30},
{0x34,0x34},
{0x38,0x38},
{0x3C,0x38},
// markAsComparedEqualToNull INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input,
TestLocalVariableBinding local) {
UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy();
result.markAsComparedEqualToNull(local);
return result;
}
},
markAsDefinitelyNonNull =
// markAsDefinitelyNonNull DEFINITION START
// start => def. non null
// prot. non null => def. non null
// prot. null => def. non null
// pot. unknown => def. non null
// pot. non null => def. non null
// pot. nn & prot. nn => def. non null
// pot. nn & pot. un => def. non null
// pot. null => def. non null
// pot. n & prot. n => def. non null
// pot. n & pot. un => def. non null
// pot. n & pot. nn => def. non null
// def. unknown => def. non null
// def. non null => def. non null
// def. null => def. non null
// markAsDefinitelyNonNull DEFINITION END
new TwoDimensionalTransformation("markAsDefinitelyNonNull",
new byte[][] {
// markAsDefinitelyNonNull INITIALIZER START
{0x00,0x28},
{0x04,0x28},
{0x08,0x28},
{0x0C,0x28},
{0x10,0x28},
{0x14,0x28},
{0x18,0x28},
{0x24,0x28},
{0x28,0x28},
{0x2C,0x28},
{0x30,0x28},
{0x34,0x28},
{0x38,0x28},
{0x3C,0x28},
// markAsDefinitelyNonNull INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input,
TestLocalVariableBinding local) {
UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy();
result.markAsDefinitelyNonNull(local);
return result;
}
},
markAsDefinitelyNull =
// markAsDefinitelyNull DEFINITION START
// start => def. null
// prot. non null => def. null
// prot. null => def. null
// pot. unknown => def. null
// pot. non null => def. null
// pot. nn & prot. nn => def. null
// pot. nn & pot. un => def. null
// pot. null => def. null
// pot. n & prot. n => def. null
// pot. n & pot. un => def. null
// pot. n & pot. nn => def. null
// def. unknown => def. null
// def. non null => def. null
// def. null => def. null
// markAsDefinitelyNull DEFINITION END
// PREMATURE add 'catch rules'
new TwoDimensionalTransformation("markAsDefinitelyNull",
new byte[][] {
// markAsDefinitelyNull INITIALIZER START
{0x00,0x30},
{0x04,0x30},
{0x08,0x30},
{0x0C,0x30},
{0x10,0x30},
{0x14,0x30},
{0x18,0x30},
{0x24,0x30},
{0x28,0x30},
{0x2C,0x30},
{0x30,0x30},
{0x34,0x30},
{0x38,0x30},
{0x3C,0x30},
// markAsDefinitelyNull INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input,
TestLocalVariableBinding local) {
UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy();
result.markAsDefinitelyNull(local);
return result;
}
},
markAsDefinitelyUnknown =
// markAsDefinitelyUnknown DEFINITION START
// start => def. unknown
// prot. non null => def. unknown
// prot. null => def. unknown
// pot. unknown => def. unknown
// pot. non null => def. unknown
// pot. nn & prot. nn => def. unknown
// pot. nn & pot. un => def. unknown
// pot. null => def. unknown
// pot. n & prot. n => def. unknown
// pot. n & pot. un => def. unknown
// pot. n & pot. nn => def. unknown
// def. unknown => def. unknown
// def. non null => def. unknown
// def. null => def. unknown
// markAsDefinitelyUnknown DEFINITION END
new TwoDimensionalTransformation("markAsDefinitelyUnknown",
new byte[][] {
// markAsDefinitelyUnknown INITIALIZER START
{0x00,0x24},
{0x04,0x24},
{0x08,0x24},
{0x0C,0x24},
{0x10,0x24},
{0x14,0x24},
{0x18,0x24},
{0x24,0x24},
{0x28,0x24},
{0x2C,0x24},
{0x30,0x24},
{0x34,0x24},
{0x38,0x24},
{0x3C,0x24},
// markAsDefinitelyUnknown INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input,
TestLocalVariableBinding local) {
UnconditionalFlowInfo result = (UnconditionalFlowInfo)input.copy();
result.markAsDefinitelyUnknown(local);
return result;
}
},
addInitializationsFrom =
// addInitializationsFrom DEFINITION START
// def. non null + def. non null => def. non null
// def. non null + def. null => def. null
// def. non null + def. unknown => def. unknown
// def. non null + pot. n & pot. nn => pot. n & pot. nn
// def. non null + pot. n & pot. un => pot. n & pot. nn
// def. non null + pot. n & prot. n => pot. n & prot. n
// def. non null + pot. nn & pot. un => def. unknown
// def. non null + pot. nn & prot. nn => def. non null
// def. non null + pot. non null => def. non null
// def. non null + pot. null => pot. n & pot. nn
// def. non null + pot. unknown => def. unknown // priv.
// def. non null + prot. non null => def. non null
// def. non null + prot. null => prot. null
// def. non null + start => def. non null
// def. null + def. non null => def. non null
// def. null + def. null => def. null
// def. null + def. unknown => def. unknown
// def. null + pot. n & pot. nn => pot. n & pot. nn
// def. null + pot. n & pot. un => pot. n & pot. un
// def. null + pot. n & prot. n => def. null
// def. null + pot. nn & pot. un => pot. n & pot. nn
// def. null + pot. nn & prot. nn => pot. nn & prot. nn
// def. null + pot. non null => pot. n & pot. nn
// def. null + pot. null => def. null
// def. null + pot. unknown => pot. n & pot. un // pot. null privileged over def. unknown
// def. null + prot. non null => prot. non null
// def. null + prot. null => def. null
// def. null + start => def. null
// def. unknown + def. non null => def. non null
// def. unknown + def. null => def. null
// def. unknown + def. unknown => def. unknown
// def. unknown + pot. n & pot. nn => pot. n & pot. nn
// def. unknown + pot. n & pot. un => pot. n & pot. un // we loose the def here, but we need the pot. null
// def. unknown + pot. n & prot. n => def. null
// def. unknown + pot. nn & pot. un => def. unknown // priv.
// def. unknown + pot. nn & prot. nn => def. non null
// def. unknown + pot. non null => def. unknown // privileging over pot. nn & pot. un
// def. unknown + pot. null => pot. n & pot. un
// def. unknown + pot. unknown => def. unknown
// def. unknown + prot. non null => def. non null
// def. unknown + prot. null => def. null
// def. unknown + start => def. unknown
// pot. n & pot. nn + def. non null => def. non null
// pot. n & pot. nn + def. null => def. null
// pot. n & pot. nn + def. unknown => def. unknown
// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn
// pot. n & pot. nn + pot. n & prot. n => pot. n & prot. n
// pot. n & pot. nn + pot. nn & pot. un => pot. n & pot. nn
// pot. n & pot. nn + pot. nn & prot. nn => pot. nn & prot. nn
// pot. n & pot. nn + pot. non null => pot. n & pot. nn
// pot. n & pot. nn + pot. null => pot. n & pot. nn
// pot. n & pot. nn + pot. unknown => pot. n & pot. nn
// pot. n & pot. nn + prot. non null => pot. nn & prot. nn
// pot. n & pot. nn + prot. null => pot. n & prot. n
// pot. n & pot. nn + start => pot. n & pot. nn
// pot. n & pot. un + def. non null => def. non null
// pot. n & pot. un + def. null => def. null
// pot. n & pot. un + def. unknown => def. unknown
// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
// pot. n & pot. un + pot. n & prot. n => pot. n & prot. n
// pot. n & pot. un + pot. nn & pot. un => pot. n & pot. nn
// pot. n & pot. un + pot. nn & prot. nn => pot. nn & prot. nn
// pot. n & pot. un + pot. non null => pot. n & pot. nn
// pot. n & pot. un + pot. null => pot. n & pot. un
// pot. n & pot. un + pot. unknown => pot. n & pot. un
// pot. n & pot. un + prot. non null => pot. nn & prot. nn
// pot. n & pot. un + prot. null => pot. n & prot. n
// pot. n & pot. un + start => pot. n & pot. un
// pot. n & prot. n + def. non null => def. non null
// pot. n & prot. n + def. null => def. null
// pot. n & prot. n + def. unknown => def. unknown
// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
// pot. n & prot. n + pot. nn & pot. un => pot. n & pot. nn
// pot. n & prot. n + pot. nn & prot. nn => pot. nn & prot. nn
// pot. n & prot. n + pot. non null => pot. n & pot. nn
// pot. n & prot. n + pot. null => pot. n & prot. n
// pot. n & prot. n + pot. unknown => pot. n & pot. un
// pot. n & prot. n + prot. non null => prot. non null
// pot. n & prot. n + prot. null => pot. n & prot. n
// pot. n & prot. n + start => pot. n & prot. n
// pot. nn & pot. un + def. non null => def. non null
// pot. nn & pot. un + def. null => def. null
// pot. nn & pot. un + def. unknown => def. unknown
// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
// pot. nn & pot. un + pot. n & prot. n => pot. n & prot. n
// pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un
// pot. nn & pot. un + pot. nn & prot. nn => pot. nn & prot. nn
// pot. nn & pot. un + pot. non null => pot. nn & pot. un
// pot. nn & pot. un + pot. null => pot. n & pot. nn
// pot. nn & pot. un + pot. unknown => pot. nn & pot. un
// pot. nn & pot. un + prot. non null => pot. nn & prot. nn
// pot. nn & pot. un + prot. null => pot. n & prot. n
// pot. nn & pot. un + start => pot. nn & pot. un
// pot. nn & prot. nn + def. non null => def. non null
// pot. nn & prot. nn + def. null => def. null
// pot. nn & prot. nn + def. unknown => def. unknown
// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & prot. n => pot. n & prot. n
// pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un
// pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn
// pot. nn & prot. nn + pot. non null => pot. nn & prot. nn
// pot. nn & prot. nn + pot. null => pot. n & pot. nn
// pot. nn & prot. nn + pot. unknown => pot. nn & pot. un
// pot. nn & prot. nn + prot. non null => pot. nn & prot. nn
// pot. nn & prot. nn + prot. null => prot. null
// pot. nn & prot. nn + start => pot. nn & prot. nn
// pot. non null + def. non null => def. non null
// pot. non null + def. null => def. null
// pot. non null + def. unknown => def. unknown
// pot. non null + pot. n & pot. nn => pot. n & pot. nn
// pot. non null + pot. n & pot. un => pot. n & pot. nn
// pot. non null + pot. n & prot. n => pot. n & prot. n
// pot. non null + pot. nn & pot. un => pot. nn & pot. un
// pot. non null + pot. nn & prot. nn => pot. nn & prot. nn
// pot. non null + pot. non null => pot. non null
// pot. non null + pot. null => pot. n & pot. nn
// pot. non null + pot. unknown => pot. nn & pot. un
// pot. non null + prot. non null => pot. nn & prot. nn
// pot. non null + prot. null => prot. null
// pot. non null + start => pot. non null
// pot. null + def. non null => def. non null
// pot. null + def. null => def. null
// pot. null + def. unknown => def. unknown
// pot. null + pot. n & pot. nn => pot. n & pot. nn
// pot. null + pot. n & pot. un => pot. n & pot. un
// pot. null + pot. n & prot. n => pot. n & prot. n
// pot. null + pot. nn & pot. un => pot. n & pot. nn
// pot. null + pot. nn & prot. nn => pot. nn & prot. nn
// pot. null + pot. non null => pot. n & pot. nn
// pot. null + pot. null => pot. null
// pot. null + pot. unknown => pot. n & pot. un
// pot. null + prot. non null => prot. non null
// pot. null + prot. null => pot. n & prot. n
// pot. null + start => pot. null
// pot. unknown + def. non null => def. non null
// pot. unknown + def. null => def. null
// pot. unknown + def. unknown => def. unknown
// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
// pot. unknown + pot. n & pot. un => pot. n & pot. un
// pot. unknown + pot. n & prot. n => pot. n & prot. n
// pot. unknown + pot. nn & pot. un => pot. nn & pot. un
// pot. unknown + pot. nn & prot. nn => pot. nn & prot. nn
// pot. unknown + pot. non null => pot. nn & pot. un
// pot. unknown + pot. null => pot. n & pot. un
// pot. unknown + pot. unknown => pot. unknown
// pot. unknown + prot. non null => pot. nn & prot. nn
// pot. unknown + prot. null => pot. n & prot. n
// pot. unknown + start => pot. unknown
// prot. non null + def. non null => def. non null
// prot. non null + def. null => def. null
// prot. non null + def. unknown => def. unknown
// prot. non null + pot. n & pot. nn => pot. n & pot. nn
// prot. non null + pot. n & pot. un => pot. n & pot. un
// prot. non null + pot. n & prot. n => pot. n & prot. n
// prot. non null + pot. nn & pot. un => pot. nn & pot. un
// prot. non null + pot. nn & prot. nn => pot. nn & prot. nn
// prot. non null + pot. non null => pot. nn & prot. nn
// prot. non null + pot. null => pot. null
// prot. non null + pot. unknown => pot. unknown
// prot. non null + prot. non null => prot. non null
// prot. non null + prot. null => prot. null
// prot. non null + start => prot. non null
// prot. null + def. non null => def. non null
// prot. null + def. null => def. null
// prot. null + def. unknown => def. unknown
// prot. null + pot. n & pot. nn => pot. n & pot. nn
// prot. null + pot. n & pot. un => pot. n & pot. un
// prot. null + pot. n & prot. n => pot. n & prot. n
// prot. null + pot. nn & pot. un => pot. nn & pot. un
// prot. null + pot. nn & prot. nn => pot. nn & prot. nn
// prot. null + pot. non null => pot. non null
// prot. null + pot. null => pot. n & prot. n
// prot. null + pot. unknown => pot. unknown
// prot. null + prot. non null => prot. non null
// prot. null + prot. null => prot. null
// prot. null + start => prot. null
// start + def. non null => def. non null
// start + def. null => def. null
// start + def. unknown => def. unknown
// start + pot. n & pot. nn => pot. n & pot. nn
// start + pot. n & pot. un => pot. n & pot. un
// start + pot. n & prot. n => pot. n & prot. n
// start + pot. nn & pot. un => pot. nn & pot. un
// start + pot. nn & prot. nn => pot. nn & prot. nn
// start + pot. non null => pot. non null
// start + pot. null => pot. null
// start + pot. unknown => pot. unknown
// start + prot. non null => prot. non null
// start + prot. null => prot. null
// start + start => start
// addInitializationsFrom DEFINITION END
new ThreeDimensionalTransformation("addInitializationsFrom",
new byte[][] {
// addInitializationsFrom INITIALIZER START
{0x00,0x00,0x00},
{0x00,0x04,0x04},
{0x00,0x08,0x08},
{0x00,0x0C,0x0C},
{0x00,0x10,0x10},
{0x00,0x14,0x14},
{0x00,0x18,0x18},
{0x00,0x24,0x24},
{0x00,0x28,0x28},
{0x00,0x2C,0x2C},
{0x00,0x30,0x30},
{0x00,0x34,0x34},
{0x00,0x38,0x38},
{0x00,0x3C,0x3C},
{0x04,0x00,0x04},
{0x04,0x04,0x04},
{0x04,0x08,0x0C},
{0x04,0x0C,0x0C},
{0x04,0x10,0x14},
{0x04,0x14,0x14},
{0x04,0x18,0x18},
{0x04,0x24,0x24},
{0x04,0x28,0x28},
{0x04,0x2C,0x2C},
{0x04,0x30,0x30},
{0x04,0x34,0x34},
{0x04,0x38,0x34},
{0x04,0x3C,0x2C},
{0x08,0x00,0x08},
{0x08,0x04,0x0C},
{0x08,0x08,0x08},
{0x08,0x0C,0x0C},
{0x08,0x10,0x18},
{0x08,0x14,0x18},
{0x08,0x18,0x18},
{0x08,0x24,0x24},
{0x08,0x28,0x28},
{0x08,0x2C,0x2C},
{0x08,0x30,0x30},
{0x08,0x34,0x34},
{0x08,0x38,0x38},
{0x08,0x3C,0x2C},
{0x0C,0x00,0x0C},
{0x0C,0x04,0x0C},
{0x0C,0x08,0x0C},
{0x0C,0x0C,0x0C},
{0x0C,0x10,0x18},
{0x0C,0x14,0x18},
{0x0C,0x18,0x18},
{0x0C,0x24,0x24},
{0x0C,0x28,0x28},
{0x0C,0x2C,0x2C},
{0x0C,0x30,0x30},
{0x0C,0x34,0x34},
{0x0C,0x38,0x34},
{0x0C,0x3C,0x2C},
{0x10,0x00,0x10},
{0x10,0x04,0x14},
{0x10,0x08,0x18},
{0x10,0x0C,0x18},
{0x10,0x10,0x10},
{0x10,0x14,0x14},
{0x10,0x18,0x18},
{0x10,0x24,0x24},
{0x10,0x28,0x28},
{0x10,0x2C,0x2C},
{0x10,0x30,0x30},
{0x10,0x34,0x34},
{0x10,0x38,0x34},
{0x10,0x3C,0x3C},
{0x14,0x00,0x14},
{0x14,0x04,0x14},
{0x14,0x08,0x18},
{0x14,0x0C,0x18},
{0x14,0x10,0x14},
{0x14,0x14,0x14},
{0x14,0x18,0x18},
{0x14,0x24,0x24},
{0x14,0x28,0x28},
{0x14,0x2C,0x2C},
{0x14,0x30,0x30},
{0x14,0x34,0x34},
{0x14,0x38,0x34},
{0x14,0x3C,0x2C},
{0x18,0x00,0x18},
{0x18,0x04,0x18},
{0x18,0x08,0x18},
{0x18,0x0C,0x18},
{0x18,0x10,0x18},
{0x18,0x14,0x18},
{0x18,0x18,0x18},
{0x18,0x24,0x24},
{0x18,0x28,0x28},
{0x18,0x2C,0x2C},
{0x18,0x30,0x30},
{0x18,0x34,0x34},
{0x18,0x38,0x34},
{0x18,0x3C,0x2C},
{0x24,0x00,0x24},
{0x24,0x04,0x24},
{0x24,0x08,0x24},
{0x24,0x0C,0x24},
{0x24,0x10,0x14},
{0x24,0x14,0x14},
{0x24,0x18,0x18},
{0x24,0x24,0x24},
{0x24,0x28,0x28},
{0x24,0x2C,0x28},
{0x24,0x30,0x30},
{0x24,0x34,0x30},
{0x24,0x38,0x30},
{0x24,0x3C,0x28},
{0x28,0x00,0x28},
{0x28,0x04,0x24},
{0x28,0x08,0x28},
{0x28,0x0C,0x24},
{0x28,0x10,0x18},
{0x28,0x14,0x18},
{0x28,0x18,0x18},
{0x28,0x24,0x24},
{0x28,0x28,0x28},
{0x28,0x2C,0x28},
{0x28,0x30,0x30},
{0x28,0x34,0x34},
{0x28,0x38,0x38},
{0x28,0x3C,0x28},
{0x2C,0x00,0x2C},
{0x2C,0x04,0x0C},
{0x2C,0x08,0x2C},
{0x2C,0x0C,0x0C},
{0x2C,0x10,0x18},
{0x2C,0x14,0x18},
{0x2C,0x18,0x18},
{0x2C,0x24,0x24},
{0x2C,0x28,0x28},
{0x2C,0x2C,0x2C},
{0x2C,0x30,0x30},
{0x2C,0x34,0x34},
{0x2C,0x38,0x38},
{0x2C,0x3C,0x2C},
{0x30,0x00,0x30},
{0x30,0x04,0x14},
{0x30,0x08,0x18},
{0x30,0x0C,0x18},
{0x30,0x10,0x30},
{0x30,0x14,0x14},
{0x30,0x18,0x18},
{0x30,0x24,0x24},
{0x30,0x28,0x28},
{0x30,0x2C,0x2C},
{0x30,0x30,0x30},
{0x30,0x34,0x30},
{0x30,0x38,0x30},
{0x30,0x3C,0x3C},
{0x34,0x00,0x34},
{0x34,0x04,0x14},
{0x34,0x08,0x18},
{0x34,0x0C,0x18},
{0x34,0x10,0x34},
{0x34,0x14,0x14},
{0x34,0x18,0x18},
{0x34,0x24,0x24},
{0x34,0x28,0x28},
{0x34,0x2C,0x2C},
{0x34,0x30,0x30},
{0x34,0x34,0x34},
{0x34,0x38,0x34},
{0x34,0x3C,0x3C},
{0x38,0x00,0x38},
{0x38,0x04,0x04},
{0x38,0x08,0x08},
{0x38,0x0C,0x0C},
{0x38,0x10,0x34},
{0x38,0x14,0x14},
{0x38,0x18,0x18},
{0x38,0x24,0x24},
{0x38,0x28,0x28},
{0x38,0x2C,0x2C},
{0x38,0x30,0x30},
{0x38,0x34,0x34},
{0x38,0x38,0x38},
{0x38,0x3C,0x3C},
{0x3C,0x00,0x3C},
{0x3C,0x04,0x04},
{0x3C,0x08,0x2C},
{0x3C,0x0C,0x0C},
{0x3C,0x10,0x10},
{0x3C,0x14,0x14},
{0x3C,0x18,0x18},
{0x3C,0x24,0x24},
{0x3C,0x28,0x28},
{0x3C,0x2C,0x2C},
{0x3C,0x30,0x30},
{0x3C,0x34,0x34},
{0x3C,0x38,0x38},
{0x3C,0x3C,0x3C},
// addInitializationsFrom INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input1,
UnconditionalFlowInfo input2) {
return (UnconditionalFlowInfo)
input1.copy().addInitializationsFrom(input2);
}
},
// addPotentialInitializationsFrom DEFINITION START
// def. non null + def. non null => def. non null
// def. non null + def. null => pot. n & pot. nn
// def. non null + def. unknown => def. unknown
// def. non null + pot. n & pot. nn => pot. n & pot. nn
// def. non null + pot. n & pot. un => pot. n & pot. nn
// def. non null + pot. n & prot. n => pot. n & pot. nn
// def. non null + pot. nn & pot. un => def. unknown
// def. non null + pot. nn & prot. nn => def. non null
// def. non null + pot. non null => def. non null
// def. non null + pot. null => pot. n & pot. nn
// def. non null + pot. unknown => def. unknown
// def. non null + prot. non null => def. non null
// def. non null + prot. null => def. non null
// def. non null + start => def. non null
// def. null + def. non null => pot. n & pot. nn
// def. null + def. null => def. null
// def. null + def. unknown => pot. n & pot. un
// def. null + pot. n & pot. nn => pot. n & pot. nn
// def. null + pot. n & pot. un => pot. n & pot. un
// def. null + pot. n & prot. n => def. null
// def. null + pot. nn & pot. un => pot. n & pot. nn
// def. null + pot. nn & prot. nn => pot. n & pot. nn
// def. null + pot. non null => pot. n & pot. nn
// def. null + pot. null => def. null
// def. null + pot. unknown => pot. n & pot. un
// def. null + prot. non null => def. null
// def. null + prot. null => def. null
// def. null + start => def. null
// def. unknown + def. non null => def. unknown
// def. unknown + def. null => pot. n & pot. un
// def. unknown + def. unknown => def. unknown
// def. unknown + pot. n & pot. nn => pot. n & pot. nn
// def. unknown + pot. n & pot. un => pot. n & pot. un
// def. unknown + pot. n & prot. n => pot. n & pot. un
// def. unknown + pot. nn & pot. un => def. unknown
// def. unknown + pot. nn & prot. nn => def. unknown
// def. unknown + pot. non null => def. unknown
// def. unknown + pot. null => pot. n & pot. un
// def. unknown + pot. unknown => def. unknown
// def. unknown + prot. non null => def. unknown
// def. unknown + prot. null => def. unknown
// def. unknown + start => def. unknown
// pot. n & pot. nn + def. non null => pot. n & pot. nn
// pot. n & pot. nn + def. null => pot. n & pot. nn
// pot. n & pot. nn + def. unknown => pot. n & pot. nn
// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn
// pot. n & pot. nn + pot. n & prot. n => pot. n & pot. nn
// pot. n & pot. nn + pot. nn & pot. un => pot. n & pot. nn
// pot. n & pot. nn + pot. nn & prot. nn => pot. n & pot. nn
// pot. n & pot. nn + pot. non null => pot. n & pot. nn
// pot. n & pot. nn + pot. null => pot. n & pot. nn
// pot. n & pot. nn + pot. unknown => pot. n & pot. nn
// pot. n & pot. nn + prot. non null => pot. n & pot. nn
// pot. n & pot. nn + prot. null => pot. n & pot. nn
// pot. n & pot. nn + start => pot. n & pot. nn
// pot. n & pot. un + def. non null => pot. n & pot. nn
// pot. n & pot. un + def. null => pot. n & pot. un
// pot. n & pot. un + def. unknown => pot. n & pot. un
// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
// pot. n & pot. un + pot. n & prot. n => pot. n & pot. un
// pot. n & pot. un + pot. nn & pot. un => pot. n & pot. nn
// pot. n & pot. un + pot. nn & prot. nn => pot. n & pot. nn
// pot. n & pot. un + pot. non null => pot. n & pot. nn
// pot. n & pot. un + pot. null => pot. n & pot. un
// pot. n & pot. un + pot. unknown => pot. n & pot. un
// pot. n & pot. un + prot. non null => pot. n & pot. un
// pot. n & pot. un + prot. null => pot. n & pot. un
// pot. n & pot. un + start => pot. n & pot. un
// pot. n & prot. n + def. non null => pot. n & pot. nn
// pot. n & prot. n + def. null => pot. n & prot. n
// pot. n & prot. n + def. unknown => pot. n & pot. un
// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
// pot. n & prot. n + pot. nn & pot. un => pot. n & pot. nn
// pot. n & prot. n + pot. nn & prot. nn => pot. n & pot. nn
// pot. n & prot. n + pot. non null => pot. n & pot. nn
// pot. n & prot. n + pot. null => pot. n & prot. n
// pot. n & prot. n + pot. unknown => pot. n & pot. un
// pot. n & prot. n + prot. non null => pot. n & prot. n
// pot. n & prot. n + prot. null => pot. n & prot. n
// pot. n & prot. n + start => pot. n & prot. n
// pot. nn & pot. un + def. non null => pot. nn & pot. un
// pot. nn & pot. un + def. null => pot. n & pot. nn
// pot. nn & pot. un + def. unknown => pot. nn & pot. un
// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
// pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn
// pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un
// pot. nn & pot. un + pot. nn & prot. nn => pot. nn & pot. un
// pot. nn & pot. un + pot. non null => pot. nn & pot. un
// pot. nn & pot. un + pot. null => pot. n & pot. nn
// pot. nn & pot. un + pot. unknown => pot. nn & pot. un
// pot. nn & pot. un + prot. non null => pot. nn & pot. un
// pot. nn & pot. un + prot. null => pot. nn & pot. un
// pot. nn & pot. un + start => pot. nn & pot. un
// pot. nn & prot. nn + def. non null => pot. nn & prot. nn
// pot. nn & prot. nn + def. null => pot. n & pot. nn
// pot. nn & prot. nn + def. unknown => pot. nn & pot. un
// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn
// pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un // see test1501
// pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn
// pot. nn & prot. nn + pot. non null => pot. nn & prot. nn
// pot. nn & prot. nn + pot. null => pot. n & pot. nn
// pot. nn & prot. nn + pot. unknown => pot. nn & pot. un
// pot. nn & prot. nn + prot. non null => pot. nn & prot. nn
// pot. nn & prot. nn + prot. null => pot. nn & prot. nn
// pot. nn & prot. nn + start => pot. nn & prot. nn
// pot. non null + def. non null => pot. non null
// pot. non null + def. null => pot. n & pot. nn
// pot. non null + def. unknown => pot. nn & pot. un
// pot. non null + pot. n & pot. nn => pot. n & pot. nn
// pot. non null + pot. n & pot. un => pot. n & pot. nn
// pot. non null + pot. n & prot. n => pot. n & pot. nn
// pot. non null + pot. nn & pot. un => pot. nn & pot. un
// pot. non null + pot. nn & prot. nn => pot. non null
// pot. non null + pot. non null => pot. non null
// pot. non null + pot. null => pot. n & pot. nn
// pot. non null + pot. unknown => pot. nn & pot. un
// pot. non null + prot. non null => pot. non null
// pot. non null + prot. null => pot. non null
// pot. non null + start => pot. non null
// pot. null + def. non null => pot. n & pot. nn
// pot. null + def. null => pot. null
// pot. null + def. unknown => pot. n & pot. un
// pot. null + pot. n & pot. nn => pot. n & pot. nn
// pot. null + pot. n & pot. un => pot. n & pot. un
// pot. null + pot. n & prot. n => pot. null
// pot. null + pot. nn & pot. un => pot. n & pot. nn
// pot. null + pot. nn & prot. nn => pot. n & pot. nn
// pot. null + pot. non null => pot. n & pot. nn
// pot. null + pot. null => pot. null
// pot. null + pot. unknown => pot. n & pot. un
// pot. null + prot. non null => pot. null
// pot. null + prot. null => pot. null
// pot. null + start => pot. null
// pot. unknown + def. non null => pot. nn & pot. un
// pot. unknown + def. null => pot. n & pot. un
// pot. unknown + def. unknown => pot. unknown
// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
// pot. unknown + pot. n & pot. un => pot. n & pot. un
// pot. unknown + pot. n & prot. n => pot. n & pot. un
// pot. unknown + pot. nn & pot. un => pot. nn & pot. un
// pot. unknown + pot. nn & prot. nn => pot. nn & pot. un
// pot. unknown + pot. non null => pot. nn & pot. un
// pot. unknown + pot. null => pot. n & pot. un
// pot. unknown + pot. unknown => pot. unknown
// pot. unknown + prot. non null => pot. unknown
// pot. unknown + prot. null => pot. unknown
// pot. unknown + start => pot. unknown
// prot. non null + def. non null => pot. nn & prot. nn
// prot. non null + def. null => pot. null
// prot. non null + def. unknown => pot. unknown
// prot. non null + pot. n & pot. nn => pot. n & pot. nn
// prot. non null + pot. n & pot. un => pot. n & pot. un
// prot. non null + pot. n & prot. n => pot. null
// prot. non null + pot. nn & pot. un => pot. nn & pot. un // see test1500
// prot. non null + pot. nn & prot. nn => pot. nn & prot. nn
// prot. non null + pot. non null => pot. nn & prot. nn
// prot. non null + pot. null => pot. null
// prot. non null + pot. unknown => pot. unknown
// prot. non null + prot. non null => prot. non null
// prot. non null + prot. null => prot. non null
// prot. non null + start => prot. non null
// prot. null + def. non null => pot. non null
// prot. null + def. null => pot. n & prot. n
// prot. null + def. unknown => pot. unknown
// prot. null + pot. n & pot. nn => pot. n & pot. nn
// prot. null + pot. n & pot. un => pot. n & pot. un
// prot. null + pot. n & prot. n => pot. n & prot. n
// prot. null + pot. nn & pot. un => pot. nn & pot. un
// prot. null + pot. nn & prot. nn => pot. non null
// prot. null + pot. non null => pot. non null
// prot. null + pot. null => pot. n & prot. n
// prot. null + pot. unknown => pot. unknown
// prot. null + prot. non null => prot. null
// prot. null + prot. null => prot. null
// prot. null + start => prot. null
// start + def. non null => pot. non null
// start + def. null => pot. null
// start + def. unknown => pot. unknown
// start + pot. n & pot. nn => pot. n & pot. nn
// start + pot. n & pot. un => pot. n & pot. un
// start + pot. n & prot. n => pot. null
// start + pot. nn & pot. un => pot. nn & pot. un
// start + pot. nn & prot. nn => pot. non null
// start + pot. non null => pot. non null
// start + pot. null => pot. null
// start + pot. unknown => pot. unknown
// start + prot. non null => start // PREMATURE may need to be tainted?
// start + prot. null => start // PREMATURE may need to be tainted?
// start + start => start
// addPotentialInitializationsFrom DEFINITION END
addPotentialInitializationsFrom =
new ThreeDimensionalTransformation("addPotentialInitializationsFrom",
new byte[][] {
// addPotentialInitializationsFrom INITIALIZER START
{0x00,0x00,0x00},
{0x00,0x04,0x04},
{0x00,0x08,0x08},
{0x00,0x0C,0x0C},
{0x00,0x10,0x10},
{0x00,0x14,0x14},
{0x00,0x18,0x18},
{0x00,0x24,0x04},
{0x00,0x28,0x08},
{0x00,0x2C,0x08},
{0x00,0x30,0x10},
{0x00,0x34,0x10},
{0x00,0x38,0x00},
{0x00,0x3C,0x00},
{0x04,0x00,0x04},
{0x04,0x04,0x04},
{0x04,0x08,0x0C},
{0x04,0x0C,0x0C},
{0x04,0x10,0x14},
{0x04,0x14,0x14},
{0x04,0x18,0x18},
{0x04,0x24,0x04},
{0x04,0x28,0x0C},
{0x04,0x2C,0x0C},
{0x04,0x30,0x14},
{0x04,0x34,0x14},
{0x04,0x38,0x04},
{0x04,0x3C,0x04},
{0x08,0x00,0x08},
{0x08,0x04,0x0C},
{0x08,0x08,0x08},
{0x08,0x0C,0x0C},
{0x08,0x10,0x18},
{0x08,0x14,0x18},
{0x08,0x18,0x18},
{0x08,0x24,0x0C},
{0x08,0x28,0x08},
{0x08,0x2C,0x08},
{0x08,0x30,0x18},
{0x08,0x34,0x18},
{0x08,0x38,0x08},
{0x08,0x3C,0x08},
{0x0C,0x00,0x0C},
{0x0C,0x04,0x0C},
{0x0C,0x08,0x0C},
{0x0C,0x0C,0x0C},
{0x0C,0x10,0x18},
{0x0C,0x14,0x18},
{0x0C,0x18,0x18},
{0x0C,0x24,0x0C},
{0x0C,0x28,0x0C},
{0x0C,0x2C,0x0C},
{0x0C,0x30,0x18},
{0x0C,0x34,0x18},
{0x0C,0x38,0x0C},
{0x0C,0x3C,0x0C},
{0x10,0x00,0x10},
{0x10,0x04,0x14},
{0x10,0x08,0x18},
{0x10,0x0C,0x18},
{0x10,0x10,0x10},
{0x10,0x14,0x14},
{0x10,0x18,0x18},
{0x10,0x24,0x14},
{0x10,0x28,0x18},
{0x10,0x2C,0x18},
{0x10,0x30,0x10},
{0x10,0x34,0x10},
{0x10,0x38,0x10},
{0x10,0x3C,0x10},
{0x14,0x00,0x14},
{0x14,0x04,0x14},
{0x14,0x08,0x18},
{0x14,0x0C,0x18},
{0x14,0x10,0x14},
{0x14,0x14,0x14},
{0x14,0x18,0x18},
{0x14,0x24,0x14},
{0x14,0x28,0x18},
{0x14,0x2C,0x18},
{0x14,0x30,0x14},
{0x14,0x34,0x14},
{0x14,0x38,0x14},
{0x14,0x3C,0x14},
{0x18,0x00,0x18},
{0x18,0x04,0x18},
{0x18,0x08,0x18},
{0x18,0x0C,0x18},
{0x18,0x10,0x18},
{0x18,0x14,0x18},
{0x18,0x18,0x18},
{0x18,0x24,0x18},
{0x18,0x28,0x18},
{0x18,0x2C,0x18},
{0x18,0x30,0x18},
{0x18,0x34,0x18},
{0x18,0x38,0x18},
{0x18,0x3C,0x18},
{0x24,0x00,0x24},
{0x24,0x04,0x24},
{0x24,0x08,0x24},
{0x24,0x0C,0x24},
{0x24,0x10,0x14},
{0x24,0x14,0x14},
{0x24,0x18,0x18},
{0x24,0x24,0x24},
{0x24,0x28,0x24},
{0x24,0x2C,0x24},
{0x24,0x30,0x14},
{0x24,0x34,0x14},
{0x24,0x38,0x24},
{0x24,0x3C,0x24},
{0x28,0x00,0x28},
{0x28,0x04,0x24},
{0x28,0x08,0x28},
{0x28,0x0C,0x24},
{0x28,0x10,0x18},
{0x28,0x14,0x18},
{0x28,0x18,0x18},
{0x28,0x24,0x24},
{0x28,0x28,0x28},
{0x28,0x2C,0x28},
{0x28,0x30,0x18},
{0x28,0x34,0x18},
{0x28,0x38,0x28},
{0x28,0x3C,0x28},
{0x2C,0x00,0x2C},
{0x2C,0x04,0x0C},
{0x2C,0x08,0x2C},
{0x2C,0x0C,0x0C},
{0x2C,0x10,0x18},
{0x2C,0x14,0x18},
{0x2C,0x18,0x18},
{0x2C,0x24,0x0C},
{0x2C,0x28,0x2C},
{0x2C,0x2C,0x2C},
{0x2C,0x30,0x18},
{0x2C,0x34,0x18},
{0x2C,0x38,0x2C},
{0x2C,0x3C,0x2C},
{0x30,0x00,0x30},
{0x30,0x04,0x14},
{0x30,0x08,0x18},
{0x30,0x0C,0x18},
{0x30,0x10,0x30},
{0x30,0x14,0x14},
{0x30,0x18,0x18},
{0x30,0x24,0x14},
{0x30,0x28,0x18},
{0x30,0x2C,0x18},
{0x30,0x30,0x30},
{0x30,0x34,0x30},
{0x30,0x38,0x30},
{0x30,0x3C,0x30},
{0x34,0x00,0x34},
{0x34,0x04,0x14},
{0x34,0x08,0x18},
{0x34,0x0C,0x18},
{0x34,0x10,0x34},
{0x34,0x14,0x14},
{0x34,0x18,0x18},
{0x34,0x24,0x14},
{0x34,0x28,0x18},
{0x34,0x2C,0x18},
{0x34,0x30,0x34},
{0x34,0x34,0x34},
{0x34,0x38,0x34},
{0x34,0x3C,0x34},
{0x38,0x00,0x38},
{0x38,0x04,0x04},
{0x38,0x08,0x08},
{0x38,0x0C,0x0C},
{0x38,0x10,0x34},
{0x38,0x14,0x14},
{0x38,0x18,0x18},
{0x38,0x24,0x04},
{0x38,0x28,0x08},
{0x38,0x2C,0x08},
{0x38,0x30,0x34},
{0x38,0x34,0x34},
{0x38,0x38,0x38},
{0x38,0x3C,0x38},
{0x3C,0x00,0x3C},
{0x3C,0x04,0x04},
{0x3C,0x08,0x2C},
{0x3C,0x0C,0x0C},
{0x3C,0x10,0x10},
{0x3C,0x14,0x14},
{0x3C,0x18,0x18},
{0x3C,0x24,0x04},
{0x3C,0x28,0x2C},
{0x3C,0x2C,0x2C},
{0x3C,0x30,0x10},
{0x3C,0x34,0x10},
{0x3C,0x38,0x3C},
{0x3C,0x3C,0x3C},
// addPotentialInitializationsFrom INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input1,
UnconditionalFlowInfo input2) {
return (UnconditionalFlowInfo)
input1.copy().addPotentialInitializationsFrom(input2);
}
},
mergedWith =
// mergedWith DEFINITION START
// def. non null + def. non null => def. non null
// def. non null + def. null => pot. n & pot. nn
// def. null + def. null => def. null
// def. unknown + def. non null => def. unknown
// def. unknown + def. null => pot. n & pot. un // pot. n priv. over def. unknown
// def. unknown + def. unknown => def. unknown
// pot. n & pot. nn + def. non null => pot. n & pot. nn
// pot. n & pot. nn + def. null => pot. n & pot. nn
// pot. n & pot. nn + def. unknown => pot. n & pot. nn
// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. un + def. non null => pot. n & pot. nn
// pot. n & pot. un + def. null => pot. n & pot. un
// pot. n & pot. un + def. unknown => pot. n & pot. un
// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
// pot. n & prot. n + def. non null => pot. n & pot. nn
// pot. n & prot. n + def. null => pot. n & prot. n
// pot. n & prot. n + def. unknown => pot. n & pot. un
// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
// pot. nn & pot. un + def. non null => pot. nn & pot. un
// pot. nn & pot. un + def. null => pot. n & pot. nn
// pot. nn & pot. un + def. unknown => pot. nn & pot. un
// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
// pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn
// pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un
// pot. nn & pot. un + pot. null => pot. n & pot. nn
// pot. nn & prot. nn + def. non null => pot. nn & prot. nn
// pot. nn & prot. nn + def. null => pot. n & pot. nn
// pot. nn & prot. nn + def. unknown => pot. nn & pot. un
// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
// pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn
// pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un
// pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn
// pot. nn & prot. nn + pot. null => pot. n & pot. nn
// pot. non null + def. non null => pot. non null
// pot. non null + def. null => pot. n & pot. nn
// pot. non null + def. unknown => pot. nn & pot. un
// pot. non null + pot. n & pot. nn => pot. n & pot. nn
// pot. non null + pot. n & pot. un => pot. n & pot. nn
// pot. non null + pot. n & prot. n => pot. n & pot. nn
// pot. non null + pot. nn & pot. un => pot. nn & pot. un
// pot. non null + pot. nn & prot. nn => pot. non null
// pot. non null + pot. non null => pot. non null
// pot. non null + pot. null => pot. n & pot. nn
// pot. null + def. non null => pot. n & pot. nn
// pot. null + def. null => pot. null
// pot. null + def. unknown => pot. n & pot. un
// pot. null + pot. n & pot. nn => pot. n & pot. nn
// pot. null + pot. n & pot. un => pot. n & pot. un
// pot. null + pot. n & prot. n => pot. null
// pot. null + pot. null => pot. null
// pot. unknown + def. non null => pot. nn & pot. un
// pot. unknown + def. null => pot. n & pot. un
// pot. unknown + def. unknown => pot. unknown
// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
// pot. unknown + pot. n & pot. un => pot. n & pot. un
// pot. unknown + pot. n & prot. n => pot. n & pot. un
// pot. unknown + pot. nn & pot. un => pot. nn & pot. un
// pot. unknown + pot. nn & prot. nn => pot. nn & pot. un
// pot. unknown + pot. non null => pot. nn & pot. un
// pot. unknown + pot. null => pot. n & pot. un
// pot. unknown + pot. unknown => pot. unknown
// prot. non null + def. non null => pot. nn & prot. nn
// prot. non null + def. null => pot. null
// prot. non null + def. unknown => def. unknown // test726
// prot. non null + pot. n & pot. nn => pot. n & pot. nn
// prot. non null + pot. n & pot. un => pot. n & pot. un
// prot. non null + pot. n & prot. n => pot. null
// prot. non null + pot. nn & pot. un => pot. nn & pot. un
// prot. non null + pot. nn & prot. nn => pot. nn & prot. nn
// prot. non null + pot. non null => pot. non null
// prot. non null + pot. null => pot. null
// prot. non null + pot. unknown => pot. unknown
// prot. non null + prot. non null => prot. non null
// prot. non null + prot. null => pot. null // PREMATURE use tainted instead
// prot. null + def. non null => pot. non null // PREMATURE should become tainted null & pot. nn... not really, depends on the three way merge... or even on the conditions that got there (pb with no contrib prot. null branch)
// prot. null + def. null => pot. n & prot. n
// prot. null + def. unknown => pot. unknown // PREMATURE possibly wrong, but no test case yet
// prot. null + pot. n & pot. nn => pot. n & pot. nn
// prot. null + pot. n & pot. un => pot. n & pot. un
// prot. null + pot. n & prot. n => pot. n & prot. n
// prot. null + pot. nn & pot. un => pot. n & pot. nn
// prot. null + pot. nn & prot. nn => pot. n & pot. nn
// prot. null + pot. non null => pot. n & pot. nn
// prot. null + pot. null => pot. null
// prot. null + pot. unknown => pot. unknown // PREMATURE possibly wrong, but no test case yet
// prot. null + prot. null => prot. null
// start + def. non null => pot. non null
// start + def. null => pot. null
// start + def. unknown => pot. unknown
// start + pot. n & pot. nn => pot. n & pot. nn
// start + pot. n & pot. un => pot. n & pot. un
// start + pot. n & prot. n => pot. null
// start + pot. nn & pot. un => pot. nn & pot. un
// start + pot. nn & prot. nn => pot. non null
// start + pot. non null => pot. non null
// start + pot. null => pot. null
// start + pot. unknown => pot. unknown
// start + prot. non null => start // PREMATURE should it taint?
// start + prot. null => start
// start + start => start
// mergedWith DEFINITION END
new SymmetricalThreeDimensionalTransformation("mergedWith",
new byte[][] {
// mergedWith INITIALIZER START
{0x00,0x00,0x00},
{0x00,0x04,0x04},
{0x00,0x08,0x08},
{0x00,0x0C,0x0C},
{0x00,0x10,0x10},
{0x00,0x14,0x14},
{0x00,0x18,0x18},
{0x00,0x24,0x04},
{0x00,0x28,0x08},
{0x00,0x2C,0x08},
{0x00,0x30,0x10},
{0x00,0x34,0x10},
{0x00,0x38,0x00},
{0x00,0x3C,0x00},
{0x04,0x04,0x04},
{0x04,0x08,0x0C},
{0x04,0x0C,0x0C},
{0x04,0x10,0x14},
{0x04,0x14,0x14},
{0x04,0x18,0x18},
{0x04,0x24,0x04},
{0x04,0x28,0x0C},
{0x04,0x2C,0x0C},
{0x04,0x30,0x14},
{0x04,0x34,0x14},
{0x08,0x08,0x08},
{0x08,0x0C,0x0C},
{0x08,0x10,0x18},
{0x08,0x14,0x18},
{0x08,0x18,0x18},
{0x08,0x24,0x0C},
{0x08,0x28,0x08},
{0x08,0x2C,0x08},
{0x08,0x30,0x18},
{0x08,0x34,0x18},
{0x0C,0x0C,0x0C},
{0x0C,0x10,0x18},
{0x0C,0x14,0x18},
{0x0C,0x18,0x18},
{0x0C,0x24,0x0C},
{0x0C,0x28,0x0C},
{0x0C,0x30,0x18},
{0x0C,0x34,0x18},
{0x10,0x10,0x10},
{0x10,0x14,0x14},
{0x10,0x18,0x18},
{0x10,0x24,0x14},
{0x10,0x28,0x18},
{0x10,0x30,0x10},
{0x10,0x34,0x10},
{0x14,0x14,0x14},
{0x14,0x18,0x18},
{0x14,0x24,0x14},
{0x14,0x28,0x18},
{0x14,0x30,0x14},
{0x18,0x18,0x18},
{0x18,0x24,0x18},
{0x18,0x28,0x18},
{0x18,0x30,0x18},
{0x24,0x24,0x24},
{0x24,0x28,0x24},
{0x24,0x30,0x14},
{0x28,0x28,0x28},
{0x28,0x30,0x18},
{0x2C,0x0C,0x0C},
{0x2C,0x10,0x18},
{0x2C,0x14,0x18},
{0x2C,0x18,0x18},
{0x2C,0x24,0x0C},
{0x2C,0x28,0x2C},
{0x2C,0x2C,0x2C},
{0x2C,0x30,0x18},
{0x2C,0x34,0x18},
{0x30,0x30,0x30},
{0x34,0x14,0x14},
{0x34,0x18,0x18},
{0x34,0x24,0x14},
{0x34,0x28,0x18},
{0x34,0x30,0x34},
{0x34,0x34,0x34},
{0x38,0x04,0x04},
{0x38,0x08,0x18},
{0x38,0x0C,0x18},
{0x38,0x10,0x10},
{0x38,0x14,0x14},
{0x38,0x18,0x18},
{0x38,0x24,0x04},
{0x38,0x28,0x08},
{0x38,0x2C,0x18},
{0x38,0x30,0x34},
{0x38,0x34,0x34},
{0x38,0x38,0x38},
{0x3C,0x04,0x04},
{0x3C,0x08,0x08},
{0x3C,0x0C,0x0C},
{0x3C,0x10,0x10},
{0x3C,0x14,0x14},
{0x3C,0x18,0x18},
{0x3C,0x24,0x24},
{0x3C,0x28,0x2C},
{0x3C,0x2C,0x2C},
{0x3C,0x30,0x10},
{0x3C,0x34,0x10},
{0x3C,0x38,0x10},
{0x3C,0x3C,0x3C},
// mergedWith INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input1,
UnconditionalFlowInfo input2) {
return input1.copy().mergedWith(input2);
}
},
newNullInfoRegistry =
// newNullInfoRegistry DEFINITION START
// start => start
// prot. non null => start
// prot. null => start
// pot. unknown => start
// pot. non null => start
// pot. nn & prot. nn => start
// pot. nn & pot. un => start
// pot. null => start
// pot. n & prot. n => start
// pot. n & pot. un => start
// pot. n & pot. nn => start
// def. unknown => pot. unknown
// def. non null => pot. non null
// def. null => pot. null
// newNullInfoRegistry DEFINITION END
new CreationalTransformation("newNullInfoRegistry",
new byte[][] {
// newNullInfoRegistry INITIALIZER START
{0x00,0x00},
{0x04,0x00},
{0x08,0x00},
{0x0C,0x00},
{0x10,0x00},
{0x14,0x00},
{0x18,0x00},
{0x24,0x04},
{0x28,0x08},
{0x2C,0x00},
{0x30,0x10},
{0x34,0x00},
{0x38,0x00},
{0x3C,0x00},
// newNullInfoRegistry INITIALIZER END
}) {
UnconditionalFlowInfo output(UnconditionalFlowInfo input) {
return NullInfoRegistryTestHarness.
testNullInfoRegistry((UnconditionalFlowInfoTestHarness) input);
}
};
public static final Transformation[] transformations = {
markAsComparedEqualToNonNull,
markAsComparedEqualToNull,
markAsDefinitelyNonNull,
markAsDefinitelyNull,
markAsDefinitelyUnknown,
addInitializationsFrom,
addPotentialInitializationsFrom,
mergedWith,
newNullInfoRegistry
};
public abstract static class Transformation {
public String name;
String definitionStartMarker, definitionEndMarker,
initializerStartMarker, initializerEndMarker;
int dimension;
public Map initializedTransitions, computedTransitions;
// PREMATURE limit public access
int failuresNb; // transient
// PREMATURE complete the test coverage for NullInfoRegistry (need to consider several classes
// of transitions so as to avoid considering NullInfoRegistry states and
// UnconditionalFlowInfo states into the same pool; moreover, cross classes
// transformations exist.
Transformation(String name) {
this.name = name;
this.definitionStartMarker = "// " + name + " " + CodeAnalysis.definitionStartMarker;
this.definitionEndMarker = "// " + name + " " + CodeAnalysis.definitionEndMarker;
this.initializerStartMarker = "// " + name + " " + CodeAnalysis.initializerStartMarker;
this.initializerEndMarker = "// " + name + " " + CodeAnalysis.initializerEndMarker;
}
abstract State[] computeOutputs(State[] inputs);
abstract void hydrate();
void fail() {
if (this.failuresNb == 0) {
System.out.println(this.name + " failures: ");
}
this.failuresNb++;
}
abstract void printTruthTables(File outputDirectory);
static boolean checkContiguity(String a, String b) {
int aLength;
if ((aLength = a.length()) != b.length()) {
System.out.println("inappropriate string length: " + a + " vs " + b);
return false;
}
int status = 0;
for (int i = 0; i < aLength; i++) {
if (a.charAt(i) != b.charAt(i)) {
status++;
}
}
if (status != 1) {
System.out.println("non contiguous strings: " + a + " vs " + b);
return false;
}
return true;
}
final static String truthTableRowNames[] = { // need a specific order to yield simplication opportunities
"000000",
"000100",
"001100",
"001000",
"011000",
"011100",
"010100",
"010000",
"110000",
"110100",
"111100",
"111000",
"101000",
"101100",
"100100",
"100000",
// PREMATURE cheated to group first four bits... reconsider
"000001",
"000011",
"000010",
"000110",
"000111",
"000101",
"001101",
"001111",
"001110",
"001010",
"001011",
"001001",
"011001",
"011011",
"011010",
"011110",
"011111",
"011101",
"010101",
"010111",
"010110",
"010010",
"010011",
"010001",
"110001",
"110011",
"110010",
"110110",
"110111",
"110101",
"111101",
"111111",
"111110",
"111010",
"111011",
"111001",
"101001",
"101011",
"101010",
"101110",
"101111",
"101101",
"100101",
"100111",
"100110",
"100010",
"100011",
"100001",
};
private static Map ranksForStates;
int rankForState(State state) {
int length;
if (ranksForStates == null) {
ranksForStates = new HashMap(length = truthTableRowNames.length);
for (int i = 0; i < length; i++) {
ranksForStates.put(truthTableRowNames[i], new Integer(i));
}
}
Integer rank;
if ((rank = (Integer) ranksForStates.get(state.printableBitsField)) != null) {
return rank.intValue();
}
return 0;
}
abstract void reinitializeFromComments(BufferedReader input, BufferedWriter output);
abstract void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output,
State[] consideredStates);
/**
* Run a test against UnconditionalFlowInfo by comparing the transitions as memorized
* into the initializer and as delivered by UnconditionalFlowInfo for various positions
* in the encoding and return the number of failures.
* @return the number of failures, that is 0 if the results match the expectations
*/
abstract int test();
}
abstract static class TwoDimensionalTransformation extends Transformation {
TwoDimensionalTransformation(String name, byte[][] transitions) {
super(name);
this.dimension = 2;
int length;
this.initializedTransitions = new HashMap(length = transitions.length);
State input1;
for (int i = 0; i < length; i++) {
if (transitions[i].length != 2) {
throw new IllegalArgumentException("transitions should have two entries");
}
input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken
if (this.initializedTransitions.get(input1) != null) {
throw new IllegalArgumentException("duplicate entry");
}
this.initializedTransitions.put(input1, State.states[transitions[i][1]]);
}
}
State[] computeOutputs(State[] inputs) {
Map resultAccumulator = new HashMap(State.stateMaxValue + 1);
hydrate(); // pre-compute all possible combinations, then cache them
for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) {
resultAccumulator.put(this.computedTransitions.get(inputs[i]), null);
}
int length;
State[] result = new State[length = resultAccumulator.size()];
Iterator resultIterator = resultAccumulator.keySet().iterator();
for (int j = 0; j < length; j++) {
result[j] = (State) resultIterator.next();
}
return result;
}
void hydrate() {
if (this.computedTransitions == null) {
State input, output;
this.computedTransitions = new HashMap(State.stateMaxValue + 1);
for (int i = 0, length = State.states.length; i < length; i++) {
output = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input = State.states[i]),
TestLocalVariableBinding.local0)).asState();
if (input.symbolic && !output.symbolic) {
System.err.println(this.name + " generates non-symbolic state " +
output + " upon entry: " + input);
}
this.computedTransitions.put(input, output);
}
}
}
abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input, TestLocalVariableBinding local);
void printTruthTables(File outputDirectory) {
try {
String outputFileName = outputDirectory.getPath() + File.separator + this.name + ".txt";
PrintWriter out = new PrintWriter(new FileOutputStream(
new File(outputFileName)));
System.out.println("Printing " + outputFileName);
out.println("======================================================");
out.println("Truth table for " + this.name );
char truthValues[][] = new char[State.statesNb][State.stateWidth];
int row, column;
for (row = 0; row < State.statesNb; row++) {
for (column = 0; column < State.stateWidth; column++) {
truthValues[row][column] = '.';
}
}
boolean keepRow[] = new boolean[State.statesNb];
Iterator i1 = this.initializedTransitions.entrySet().iterator();
while (i1.hasNext()) {
Map.Entry transitionsSet = (Map.Entry) i1.next();
State input = (State) transitionsSet.getKey();
keepRow[row = rankForState(input)] = true;
for (int bit = 0; bit < State.stateWidth; bit++) {
truthValues[row][bit] =
((State) transitionsSet.getValue()).printableBitsField.charAt(bit);
}
}
StringBuffer line;
line = new StringBuffer(140);
line.append(" ");
for (int i = 1; i <= State.stateWidth; i++) {
line.append(i);
line.append(' ');
}
out.println(line);
line = new StringBuffer(140);
line.append(" ---------------------");
out.println(line);
for (row = 0; row < State.statesNb; row++) {
if (keepRow[row]) {
line = new StringBuffer(140);
line.append(truthTableRowNames[row]);
line.append(" | ");
for (int i = 0; i < State.stateWidth; i++) {
line.append(truthValues[row][i]);
line.append(' ');
}
out.println(line);
}
}
out.println("======================================================");
out.flush();
out.close();
}
catch (Throwable t) {
// PREMATURE improve error handling
}
}
void reinitializeFromComments(BufferedReader input, BufferedWriter output) {
String line, tab = "";
int cursor;
char c;
this.initializedTransitions = new HashMap(State.stateMaxValue);
int lineNumber = 0;
try {
while ((line = input.readLine()) != null) {
lineNumber++;
output.write(line);
output.write('\n');
if ((cursor = line.indexOf(this.definitionStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.definitionEndMarker) == -1) {
lineNumber++;
final int
start = 0,
commentStart = 1,
commentFound = 2,
firstState = 10,
firstStateWS = 11,
implies = 20,
impliesWS = 21,
secondState = 30,
secondStateWS = 31, // caveat, multi-state
error = 99;
int state = start,
firstStateStart = 0, firstStateEnd = 0, firstStateWhiteSpace = 0,
secondStateStart = 0, secondStateEnd = 0, secondStateWhiteSpace = 0;
char current;
analysis: for (int i = 0, length = line.length(); i < length; i++) {
current = line.charAt(i);
switch (state) {
case start:
if (current == '/') {
state = commentStart;
} else if (! Character.isWhitespace(current)) {
state = error;
break analysis;
}
break;
case commentStart:
if (current == '/') {
state = commentFound;
} else {
state = error;
break analysis;
}
break;
case commentFound:
if (! Character.isWhitespace(current)) {
firstStateStart = firstStateEnd = i;
state = firstState;
}
break;
case firstState:
if (Character.isWhitespace(current)) {
state = firstStateWS;
firstStateWhiteSpace = 1;
} else {
firstStateEnd++;
}
break;
case firstStateWS:
if (current == '=') {
state = implies;
} else if (Character.isWhitespace(current)) {
firstStateWhiteSpace++;
} else {
state = firstState;
firstStateEnd += firstStateWhiteSpace + 1;
}
break;
case implies:
if (current == '>') {
state = impliesWS;
} else {
state = error;
break analysis;
}
break;
case impliesWS:
if (! Character.isWhitespace(current)) {
secondStateStart = secondStateEnd = i;
state = secondState;
}
break;
case secondState:
if (current == '/') {
break analysis;
} else if (Character.isWhitespace(current)) {
state = secondStateWS;
secondStateWhiteSpace = 1;
} else {
secondStateEnd++;
}
break;
case secondStateWS:
if (current == '/') {
state = secondState;
break analysis;
} else if (current == 'C') {
state++;
} else if (Character.isWhitespace(current)) {
secondStateWhiteSpace++;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 1;
}
break;
case secondStateWS + 1:
if (current == '/') {
state = secondState;
break analysis;
} else if (current == 'H') {
state++;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 2;
}
break;
case secondStateWS + 2:
if (current == '/') {
state = secondState;
break analysis;
} else if (current == 'E') {
state++;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 3;
}
break;
case secondStateWS + 3:
if (current == '/') {
state = secondState;
break analysis;
} else if (current == 'C') {
state++;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 4;
}
break;
case secondStateWS + 4:
if (current == '/' || current == 'K') {
state = secondState;
break analysis;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 5;
}
break;
}
}
if (state == error || state < secondState) {
System.err.println("Could not interpret comment definition"); // PREMATURE improve diagnostic
} else {
if (state > secondStateWS) {
secondStateEnd += (state - secondState);
}
String stateName;
State first, second;
if ((first = State.fromSymbolicName(
stateName = line.substring(firstStateStart, firstStateEnd + 1)))
== null) {
System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic
}
if ((second = State.fromSymbolicName(
stateName = line.substring(secondStateStart, secondStateEnd + 1)))
== null) {
System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic
}
if (first != null && second != null) {
if (this.initializedTransitions.get(first) != null) {
System.err.println("Line " + lineNumber + ": Skipping duplicate entry for state: " + first); // PREMATURE improve diagnostic
} else {
this.initializedTransitions.put(first, second);
}
}
}
output.write(line);
output.write('\n');
}
Iterator firsts = State.symbolicStates();
State first;
while (firsts.hasNext()) {
first = (State) firsts.next();
if (this.initializedTransitions.get(first) == null) {
System.err.println("Adding missing transition for state: " + first);
output.write(tab);
output.write("// ");
output.write(first.toString());
output.write(" => start\t\t CHECK\n");
}
}
}
output.write(tab + this.definitionEndMarker + "\n");
}
if (line != null && (cursor = line.indexOf(this.initializerStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
tab = "";
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.initializerEndMarker) == -1) {
// loop
}
SortedMap sorted = new TreeMap(this.initializedTransitions);
Iterator transitions = sorted.entrySet().iterator();
Map.Entry transition;
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
output.write(tab);
output.write('{');
output.write(((State)transition.getKey()).hexString);
output.write(',');
output.write(((State)transition.getValue()).hexString);
output.write("},");
output.write('\n');
}
output.write(tab + this.initializerEndMarker + "\n");
}
}
}
output.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output,
State[] consideredStates) {
String line, tab = "";
int cursor;
char c;
State result;
try {
while ((line = input.readLine()) != null) {
output.write(line);
output.write('\n');
if ((cursor = line.indexOf(this.definitionStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.definitionEndMarker) == -1) {
// loop
}
int i, length;
for (i = 0, length = consideredStates.length; i < length; i++) {
output.write(tab);
output.write("// ");
output.write(consideredStates[i].name);
output.write(" => ");
output.write(
(result = (State) this.computedTransitions.get(consideredStates[i])).name);
if (!result.symbolic ||
result != this.initializedTransitions.get(consideredStates[i])) {
output.write("\t\t CHECK");
}
output.write('\n');
}
output.write(tab + this.definitionEndMarker + "\n");
}
}
if (line != null && (cursor = line.indexOf(this.initializerStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
tab = "";
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.initializerEndMarker) == -1) {
// loop
}
int i, length;
for (i = 0, length = consideredStates.length; i < length; i++) {
output.write(tab);
output.write('{');
output.write(consideredStates[i].hexString);
output.write(',');
output.write(
((State) this.computedTransitions.get(consideredStates[i])).hexString);
output.write("},");
output.write('\n');
}
output.write(tab + this.initializerEndMarker + "\n");
}
}
}
output.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
int test() {
Iterator transitions = this.initializedTransitions.entrySet().iterator();
State input, expectedOutput, effectiveOutput;
Map.Entry transition;
this.failuresNb = 0; // reset
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
input = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input),
TestLocalVariableBinding.local0)).asState();
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" instead of: " + expectedOutput.printableBitsField);
}
}
transitions = this.initializedTransitions.entrySet().iterator();
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
input = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input, 64),
TestLocalVariableBinding.local64)).asState(64);
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64) instead of: " + expectedOutput.printableBitsField);
}
if (input == State.start) {
effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(expectedOutput),
TestLocalVariableBinding.local64)).asState(64);
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 64) instead of: " + expectedOutput.printableBitsField);
}
}
}
transitions = this.initializedTransitions.entrySet().iterator();
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
input = (State) transition.getKey();
if (input == State.start) {
expectedOutput = (State) transition.getValue();
effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(expectedOutput, 64),
TestLocalVariableBinding.local128)).asState(128);
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 128) instead of: " + expectedOutput.printableBitsField);
}
}
}
return this.failuresNb;
}
}
abstract static class CreationalTransformation extends TwoDimensionalTransformation {
CreationalTransformation(String name, byte[][] transitions) {
super(name, transitions);
}
void hydrate() {
if (this.computedTransitions == null) {
State input, output;
this.computedTransitions = new HashMap(State.stateMaxValue + 1);
for (int i = 0, length = State.states.length; i < length; i++) {
output = ((NullInfoRegistryTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input = State.states[i]),
TestLocalVariableBinding.local0)).asState();
if (input.symbolic && !output.symbolic) {
System.err.println(this.name + " generates non-symbolic state " +
output + " upon entry: " + input);
}
this.computedTransitions.put(input, output);
}
}
}
UnconditionalFlowInfo output(UnconditionalFlowInfo input, TestLocalVariableBinding local) {
return output(input);
}
abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input);
int test() {
Iterator transitions = this.initializedTransitions.entrySet().iterator();
State input, expectedOutput, effectiveOutput;
Map.Entry transition;
this.failuresNb = 0; // reset
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
input = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((NullInfoRegistryTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input),
TestLocalVariableBinding.local0)).asState();
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" instead of: " + expectedOutput.printableBitsField);
}
}
transitions = this.initializedTransitions.entrySet().iterator();
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
input = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((NullInfoRegistryTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input, 64))).asState(64);
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64) instead of: " + expectedOutput.printableBitsField);
}
}
return this.failuresNb;
}
}
public abstract static class ThreeDimensionalTransformation extends Transformation {
private static final boolean CHECKING_ROW_NAMES = false;
ThreeDimensionalTransformation(String name) {
super(name);
this.dimension = 3;
}
ThreeDimensionalTransformation(String name, byte[][] transitions) {
super(name);
this.dimension = 3;
int length;
this.initializedTransitions = new HashMap(length = transitions.length);
State input1, input2;
for (int i = 0; i < length; i++) {
if (transitions[i].length != 3) {
throw new IllegalArgumentException("transitions should have three entries");
}
input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken
input2 = State.states[transitions[i][1]];
Map transitionsForInput1 = (Map) this.initializedTransitions.get(input1);
if (transitionsForInput1 == null) {
transitionsForInput1 = new HashMap(length);
this.initializedTransitions.put(input1, transitionsForInput1);
}
if (transitionsForInput1.get(input2) != null) {
throw new IllegalArgumentException("duplicate entry");
}
transitionsForInput1.put(input2, State.states[transitions[i][2]]);
}
}
State[] computeOutputs(State[] inputs) {
Map resultAccumulator = new HashMap(State.stateMaxValue + 1);
hydrate(); // pre-compute all possible combinations, then cache them
for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) {
for (int i2 = 0; i2 < inputsLength; i2++) {
resultAccumulator.put(
((Map) this.computedTransitions.get(inputs[i])).get(inputs[i2]), null);
}
}
int length;
State[] result = new State[length = resultAccumulator.size()];
Iterator resultIterator = resultAccumulator.keySet().iterator();
for (int j = 0; j < length; j++) {
result[j] = (State) resultIterator.next();
}
return result;
}
void hydrate() {
if (this.computedTransitions == null) {
State input1, input2, output;
this.computedTransitions = new HashMap(State.stateMaxValue + 1);
Map entry;
for (int i = 0, length = State.states.length; i < length; i++) {
entry = new HashMap(State.stateMaxValue + 1);
this.computedTransitions.put(input1 = State.states[i], entry);
for (int j = 0; j < length; j++) {
output = ((UnconditionalFlowInfoTestHarness)
output(UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input1),
UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2 = State.states[j]))).asState();
if (input1.symbolic && input2.symbolic && !output.symbolic) {
System.err.println(this.name + " generates non-symbolic state " +
output + " upon entry: " + input1 + " + " + input2);
}
entry.put(input2, output);
}
}
}
}
abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input1, UnconditionalFlowInfo input2);
void printDefinitions(BufferedWriter output, State[] consideredStates, String tab)
throws IOException {
int i, j, length;
State result;
for (i = 0, length = consideredStates.length; i < length; i++) {
for (j = 0; j < length; j++) {
output.write(tab);
output.write("// ");
output.write(consideredStates[i].name);
output.write(" + ");
output.write(consideredStates[j].name);
output.write(" => ");
output.write(
(result = (State)
((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name);
if (!result.symbolic ||
result != this.initializedTransitions.get(consideredStates[i])) {
output.write("\t\t CHECK");
}
output.write('\n');
}
}
}
void printInitializers(BufferedWriter output, State[] consideredStates, String tab)
throws IOException {
int i, j, length;
for (i = 0, length = consideredStates.length; i < length; i++) {
for (j = 0; j < length; j++) {
output.write(tab);
output.write('{');
output.write(consideredStates[i].hexString);
output.write(',');
output.write(consideredStates[j].hexString);
output.write(',');
output.write(
((State)
((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).hexString);
output.write("},");
output.write('\n');
}
}
}
void printMissingEntries(BufferedWriter output, String tab) throws IOException {
Iterator firsts = State.symbolicStates(), seconds;
State first, second;
Map transitions;
while (firsts.hasNext()) {
first = (State) firsts.next();
seconds = State.symbolicStates();
if ((transitions = (Map) this.initializedTransitions.get(first))
== null) {
while (seconds.hasNext()) {
second = (State) seconds.next();
System.err.println("Adding missing transition for states (" + first + ", " + second + ")");
output.write(tab);
output.write("// ");
output.write(first.toString());
output.write(" + ");
output.write(second.toString());
output.write(" => start\t\t CHECK\n");
}
} else {
while (seconds.hasNext()) {
second = (State) seconds.next();
if (transitions.get(second) == null) {
System.err.println("Adding missing transition for states (" + first + ", " + second + ")");
output.write(tab);
output.write("// ");
output.write(first.toString());
output.write(" + ");
output.write(second.toString());
output.write(" => start\t\t CHECK\n");
}
}
}
}
}
void printTruthTables(File outputDirectory) {
for (int bit = 1; bit <= State.stateWidth; bit++) {
try {
String outputFileName = outputDirectory.getPath() + File.separator + this.name + "_" + bit + ".txt";
PrintWriter out = new PrintWriter(new FileOutputStream(
new File(outputFileName)));
System.out.println("Printing " + outputFileName);
out.println("======================================================");
out.println("Truth table for " + this.name + " null bit " + bit);
char truthValues[][] = new char[State.statesNb][State.statesNb];
int row, column;
for (row = 0; row < State.statesNb; row++) {
for (column = 0; column < State.statesNb; column++) {
truthValues[row][column] = '.';
}
}
if (CHECKING_ROW_NAMES) { // checking row names
boolean gotProblem = false;
if (truthTableRowNames.length > State.statesNb) {
System.out.println("row names table contains too many rows");
gotProblem = true;
}
else if (truthTableRowNames.length < State.statesNb) {
System.out.println("row names table contains too few rows");
gotProblem = true;
}
Map check = new HashMap(State.statesNb);
for (row = 0; row < truthTableRowNames.length; row++) {
if (check.containsKey(truthTableRowNames[row])) {
System.out.println("duplicate row: " + truthTableRowNames[row]);
gotProblem = true;
}
else {
check.put(truthTableRowNames[row], null);
}
if (row > 0 && !checkContiguity(truthTableRowNames[row - 1], truthTableRowNames[row])) {
gotProblem = true;
}
}
// assertFalse("invalid rows table", gotProblem);
}
boolean keepRow[] = new boolean[State.statesNb],
keepColumn[] = new boolean[State.statesNb];
Iterator i1 = this.initializedTransitions.entrySet().iterator();
while (i1.hasNext()) {
Map.Entry transitionsSet = (Map.Entry) i1.next();
State first = (State) transitionsSet.getKey();
Iterator i2 = ((Map) transitionsSet.getValue()).entrySet().iterator();
while (i2.hasNext()) {
Map.Entry transition = (Map.Entry) i2.next();
mark(truthValues, keepRow, keepColumn, rankForState(first),
rankForState((State) transition.getKey()),
((State) transition.getValue()).printableBitsField.charAt(bit - 1));
}
}
for (row = 0; row < State.statesNb; row += 2) {
if (keepRow[row]) {
keepRow[row + 1] = true;
}
else if (keepRow[row + 1]) {
keepRow[row] = true;
}
if (keepColumn[row]) {
keepColumn[row + 1] = true;
}
else if (keepColumn[row + 1]) {
keepColumn[row] = true;
}
}
StringBuffer line;
for (int i = 0; i < State.stateWidth; i++) {
line = new StringBuffer(140);
line.append(" ");
for (column = 0; column < State.statesNb; column++) {
if (keepColumn[column]) {
line.append(truthTableRowNames[column].charAt(i));
line.append(' ');
}
}
out.println(line);
}
line = new StringBuffer(140);
line.append(" --");
for (column = 0; column < State.statesNb; column++) {
if (keepColumn[column]) {
line.append('-');
line.append('-');
}
}
out.println(line);
for (row = 0; row < State.statesNb; row++) {
if (keepRow[row]) {
line = new StringBuffer(140);
line.append(truthTableRowNames[row]);
line.append(" | ");
for (column = 0; column < State.statesNb; column++) {
if (keepColumn[column]) {
line.append(truthValues[row][column]);
line.append(' ');
}
}
out.println(line);
}
}
out.println("======================================================");
out.flush();
out.close();
}
catch (Throwable t) {
// PREMATURE improve error handling
}
}
}
void mark(char truthValues[][], boolean keepRow[], boolean keepColumn[],
int row, int column, char value) {
truthValues[row][column] = value;
keepRow[row] = true;
keepColumn[column] = true;
}
void reinitializeFromComments(BufferedReader input, BufferedWriter output) {
String line, tab = "";
int cursor;
char c;
this.initializedTransitions = new HashMap(State.stateMaxValue);
int lineNumber = 0;
try {
while ((line = input.readLine()) != null) {
lineNumber++;
output.write(line);
output.write('\n');
if ((cursor = line.indexOf(this.definitionStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.definitionEndMarker) == -1) {
lineNumber++;
final int
start = 0,
commentStart = 1,
commentFound = 2,
firstState = 10,
firstStateWS = 11,
plus = 20,
secondState = 30,
secondStateWS = 31,
implies = 40,
impliesWS = 41,
thirdState = 50,
thirdStateWS = 51, // caveat, multi-state
error = 99;
int state = start,
firstStateStart = 0, firstStateEnd = 0, firstStateWhiteSpace = 0,
secondStateStart = 0, secondStateEnd = 0, secondStateWhiteSpace = 0,
thirdStateStart = 0, thirdStateEnd = 0, thirdStateWhiteSpace = 0;
char current;
analysis: for (int i = 0, length = line.length(); i < length; i++) {
current = line.charAt(i);
switch (state) {
case start:
if (current == '/') {
state = commentStart;
} else if (! Character.isWhitespace(current)) {
state = error;
break analysis;
}
break;
case commentStart:
if (current == '/') {
state = commentFound;
} else {
state = error;
break analysis;
}
break;
case commentFound:
if (! Character.isWhitespace(current)) {
firstStateStart = firstStateEnd = i;
state = firstState;
}
break;
case firstState:
if (Character.isWhitespace(current)) {
state = firstStateWS;
firstStateWhiteSpace = 1;
} else {
firstStateEnd++;
}
break;
case firstStateWS:
if (current == '+') {
state = plus;
} else if (Character.isWhitespace(current)) {
firstStateWhiteSpace++;
} else {
state = firstState;
firstStateEnd += firstStateWhiteSpace + 1;
}
break;
case plus:
if (! Character.isWhitespace(current)) {
secondStateStart = secondStateEnd = i;
state = secondState;
}
break;
case secondState:
if (Character.isWhitespace(current)) {
state = secondStateWS;
secondStateWhiteSpace = 1;
} else {
secondStateEnd++;
}
break;
case secondStateWS:
if (current == '=') {
state = implies;
} else if (Character.isWhitespace(current)) {
secondStateWhiteSpace++;
} else {
state = secondState;
secondStateEnd += secondStateWhiteSpace + 1;
}
break;
case implies:
if (current == '>') {
state = impliesWS;
} else {
state = error;
break analysis;
}
break;
case impliesWS:
if (! Character.isWhitespace(current)) {
thirdStateStart = thirdStateEnd = i;
state = thirdState;
}
break;
case thirdState:
if (current == '/') {
break analysis;
} else if (Character.isWhitespace(current)) {
state = thirdStateWS;
thirdStateWhiteSpace = 1;
} else {
thirdStateEnd++;
}
break;
case thirdStateWS:
if (current == '/') {
state = thirdState;
break analysis;
} else if (current == 'C') {
state++;
} else if (Character.isWhitespace(current)) {
thirdStateWhiteSpace++;
} else {
state = thirdState;
thirdStateEnd += thirdStateWhiteSpace + 1;
}
break;
case thirdStateWS + 1:
if (current == '/') {
state = thirdState;
break analysis;
} else if (current == 'H') {
state++;
} else {
state = thirdState;
thirdStateEnd += thirdStateWhiteSpace + 2;
}
break;
case thirdStateWS + 2:
if (current == '/') {
state = thirdState;
break analysis;
} else if (current == 'E') {
state++;
} else {
state = thirdState;
thirdStateEnd += thirdStateWhiteSpace + 3;
}
break;
case thirdStateWS + 3:
if (current == '/') {
state = thirdState;
break analysis;
} else if (current == 'C') {
state++;
} else {
state = thirdState;
thirdStateEnd += thirdStateWhiteSpace + 4;
}
break;
case thirdStateWS + 4:
if (current == '/' || current == 'K') {
state = thirdState;
break analysis;
} else {
state = thirdState;
thirdStateEnd += thirdStateWhiteSpace + 5;
}
break;
}
}
if (state == error || state < thirdState) {
System.err.println("Could not interpret comment definition"); // PREMATURE improve diagnostic
} else {
if (state > thirdStateWS) {
thirdStateEnd += (state - thirdState);
}
String stateName;
State first, second, third;
if ((first = State.fromSymbolicName(
stateName = line.substring(firstStateStart, firstStateEnd + 1)))
== null) {
System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic
}
if ((second = State.fromSymbolicName(
stateName = line.substring(secondStateStart, secondStateEnd + 1)))
== null) {
System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic
}
if ((third = State.fromSymbolicName(
stateName = line.substring(thirdStateStart, thirdStateEnd + 1)))
== null) {
System.err.println("Could not find state: " + stateName); // PREMATURE improve diagnostic
}
if (first != null && second != null && third != null) {
Map transitions;
if ((transitions = (Map) this.initializedTransitions.get(first)) == null) {
transitions = new HashMap(State.stateMaxValue + 1);
this.initializedTransitions.put(first, transitions);
}
if (transitions.get(second) != null) {
System.err.println("Line " + lineNumber + ": Skipping duplicate entry for states: (" + first
+ ", " + second + ")"); // PREMATURE improve diagnostic
} else {
transitions.put(second, third);
}
}
}
output.write(line);
output.write('\n');
}
}
printMissingEntries(output, tab);
output.write(tab + this.definitionEndMarker + "\n");
}
if (line != null && (cursor = line.indexOf(this.initializerStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
tab = "";
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.initializerEndMarker) == -1) {
// loop
}
SortedMap sortedTransitionsSet = new TreeMap(this.initializedTransitions);
Iterator transitionsSets = sortedTransitionsSet.entrySet().iterator();
Map.Entry transitionsSet;
while (transitionsSets.hasNext()) {
transitionsSet = (Map.Entry) transitionsSets.next();
SortedMap sortedTransitions = new TreeMap((Map) transitionsSet.getValue());
Iterator transitions = sortedTransitions.entrySet().iterator();
Map.Entry transition;
while (transitions.hasNext()) {
transition = (Map.Entry) transitions.next();
output.write(tab);
output.write('{');
output.write(((State)transitionsSet.getKey()).hexString);
output.write(',');
output.write(((State)transition.getKey()).hexString);
output.write(',');
output.write(((State)transition.getValue()).hexString);
output.write("},");
output.write('\n');
}
}
output.write(tab + this.initializerEndMarker + "\n");
}
}
}
output.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
void reinitializeFromComputedValues(BufferedReader input, BufferedWriter output,
State[] consideredStates) {
String line, tab = "";
int cursor;
char c;
try {
while ((line = input.readLine()) != null) {
output.write(line);
output.write('\n');
if ((cursor = line.indexOf(this.definitionStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.definitionEndMarker) == -1) {
// loop
}
printDefinitions(output, consideredStates, tab);
output.write(tab + this.definitionEndMarker + "\n");
}
}
if (line != null && (cursor = line.indexOf(this.initializerStartMarker)) != -1) {
// check the line format
boolean reachedStart = true;
tab = "";
for (int i = 0; i < cursor; i++) {
if (!Character.isWhitespace(c = line.charAt(i))) {
reachedStart = false;
break;
}
else {
tab += c;
}
}
if (reachedStart) {
while ((line = input.readLine()) != null &&
line.indexOf(this.initializerEndMarker) == -1) {
// loop
}
printInitializers(output, consideredStates, tab);
output.write(tab + this.initializerEndMarker + "\n");
}
}
}
output.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
int test() {
return test(1, false);
}
int test(int combinationTestsLoopsNb, boolean skipHighOrderBits) {
Iterator transitionsSetsIterator, transitionsIterator;
State input1, input2, expectedOutput, effectiveOutput;
Map.Entry transition, transitionsSet;
this.failuresNb = 0; // reset
this.failuresNb = 0; // reset
long start = 0;
if (combinationTestsLoopsNb > 1) {
start = System.currentTimeMillis();
}
for (int l = 0; l < combinationTestsLoopsNb ; l++) {
transitionsSetsIterator = this.initializedTransitions.entrySet().iterator();
while (transitionsSetsIterator.hasNext()) {
transitionsSet = (Map.Entry) transitionsSetsIterator.next();
input1 = (State) transitionsSet.getKey();
transitionsIterator = ((Map) transitionsSet.getValue()).
entrySet().iterator();
while (transitionsIterator.hasNext()) {
transition = (Map.Entry) transitionsIterator.next();
input2 = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((UnconditionalFlowInfoTestHarness) output(
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1),
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2)))
.asState();
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" instead of: " + expectedOutput.printableBitsField);
}
}
}
}
if (combinationTestsLoopsNb > 1) {
System.out.println(this.name + "...\t\t" + combinationTestsLoopsNb + "\t" +
(System.currentTimeMillis() - start));
}
// PREMATURE optimize test (extraneous allocations and copies)
// PREMATURE optimize test (extraneous iterations - undup)
if (!skipHighOrderBits) {
UnconditionalFlowInfoTestHarness
zero = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(State.start),
left, right, left64, right64, left128, right128,
special = (UnconditionalFlowInfoTestHarness) zero.copy();
special.grow(64); // allocates one extra without adding null info
transitionsSetsIterator = this.initializedTransitions.entrySet().iterator();
while (transitionsSetsIterator.hasNext()) {
transitionsSet = (Map.Entry) transitionsSetsIterator.next();
input1 = (State) transitionsSet.getKey();
transitionsIterator = ((Map) transitionsSet.getValue()).
entrySet().iterator();
while (transitionsIterator.hasNext()) {
transition = (Map.Entry) transitionsIterator.next();
input2 = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
left = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input1);
left64 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input1, 64);
left128 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input1, 128);
right = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2);
right64 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2, 64);
right128 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2, 128);
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left64, right64)).asState(64)) !=
expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, 64) - instead of: " + expectedOutput.printableBitsField);
}
if (input1 == State.start) {
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, right)).asState()) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 128, 1) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(zero, right64)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero, 64) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, right64)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 128, 64) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(zero, right128)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero, 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right64, right128)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 64, 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(special, right128)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (special zero, 128) - instead of: " + expectedOutput.printableBitsField);
}
}
if (input2 == State.start) {
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left, left128)).asState()) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (1, zero 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left64, zero)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, zero) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left64, left128)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, zero 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left128, zero)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (128, zero) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left128, left64)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (128, zero 64) - instead of: " + expectedOutput.printableBitsField);
}
}
}
}
}
return this.failuresNb;
}
}
public abstract static class SymmetricalThreeDimensionalTransformation
extends ThreeDimensionalTransformation{
SymmetricalThreeDimensionalTransformation(String name, byte[][] transitions) {
super(name);
int length;
this.initializedTransitions = new HashMap((length = transitions.length) * 2 - 1);
State input1, input2;
for (int i = 0; i < length; i++) {
if (transitions[i].length != 3) {
throw new IllegalArgumentException("transitions should have three entries");
}
if (transitions[i][0] <= transitions[i][1]) {
input1 = State.states[transitions[i][0]]; // array out of bounds exception if broken
input2 = State.states[transitions[i][1]];
}
else {
input1 = State.states[transitions[i][1]];
input2 = State.states[transitions[i][0]];
}
Map transitionsForInput1 = (Map) this.initializedTransitions.get(input1);
if (transitionsForInput1 == null) {
transitionsForInput1 = new HashMap(length);
this.initializedTransitions.put(input1, transitionsForInput1);
}
if (transitionsForInput1.get(input2) != null) {
throw new IllegalArgumentException("duplicate entry");
}
transitionsForInput1.put(input2, State.states[transitions[i][2]]);
}
}
void hydrate() {
super.hydrate();
checkSymmetry(this.computedTransitions);
}
private void checkSymmetry(Map map) {
State input1, input2, result;
Map.Entry entry1, entry2;
Map transition;
Iterator transitions1 = map.entrySet().iterator(), transitions2;
while (transitions1.hasNext()) {
entry1 = (Map.Entry) transitions1.next();
input1 = (State) entry1.getKey();
transition = (Map) entry1.getValue();
transitions2 = transition.entrySet().iterator();
while (transitions2.hasNext()) {
entry2 = (Map.Entry) transitions2.next();
input2 = (State) entry2.getKey();
result = (State) entry2.getValue();
if (result != ((Map) map.get(input2)).get(input1) && input1.symbolic && input2.symbolic) {
System.err.println("symmetry mismatch: " + input1 + " + " +
input2 + " -> " + result + "/" + ((Map) map.get(input2)).get(input1));
}
}
}
}
void mark(char truthValues[][], boolean keepRow[], boolean keepColumn[],
int row, int column, char value) {
truthValues[row][column] = truthValues[column][row] = value;
keepRow[row] = true;
keepColumn[column] = true;
keepRow[column] = true;
keepColumn[row] = true;
}
void printDefinitions(BufferedWriter output, State[] consideredStates, String tab)
throws IOException {
// only difference with parent is that we print only half of possible
// combinations
int i, j, length;
State result;
for (i = 0, length = consideredStates.length; i < length; i++) {
for (j = i; j < length; j++) {
output.write(tab);
output.write("// ");
output.write(consideredStates[i].name);
output.write(" + ");
output.write(consideredStates[j].name);
output.write(" => ");
output.write(
(result = (State)
((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name);
if (!result.symbolic ||
result != this.initializedTransitions.get(consideredStates[i])) {
output.write("\t\t CHECK");
}
output.write('\n');
}
}
}
void printInitializers(BufferedWriter output, State[] consideredStates, String tab)
throws IOException {
// only difference with parent is that we print only half of possible
// combinations
int i, j, length;
for (i = 0, length = consideredStates.length; i < length; i++) {
for (j = i; j < length; j++) {
output.write(tab);
output.write('{');
output.write(consideredStates[i].hexString);
output.write(',');
output.write(consideredStates[j].hexString);
output.write(',');
output.write(
((State)
((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).hexString);
output.write("},");
output.write('\n');
}
}
}
void printMissingEntries(BufferedWriter output, String tab) throws IOException {
Iterator firsts = State.symbolicStates(), seconds;
State first, second;
while (firsts.hasNext()) {
first = (State) firsts.next();
seconds = State.symbolicStates();
while (seconds.hasNext()) {
second = (State) seconds.next();
if (!checkPair(first, second)) {
addPair(first, second);
System.err.println("Adding missing transition for states (" + first + ", " + second + ")");
output.write(tab);
output.write("// ");
output.write(first.toString());
output.write(" + ");
output.write(second.toString());
output.write(" => start\t\t CHECK\n");
}
}
}
}
private boolean checkPair(State s1, State s2) {
Map transitions;
if ((transitions = (Map) this.initializedTransitions.get(s1)) != null) {
if (transitions.get(s2) != null) {
return true;
}
}
if ((transitions = (Map) this.initializedTransitions.get(s2)) != null) {
if (transitions.get(s1) != null) {
return true;
}
}
return false;
}
private void addPair(State s1, State s2) {
Map transitions;
if ((transitions = (Map) this.initializedTransitions.get(s1)) == null) {
transitions = new HashMap();
this.initializedTransitions.put(s1, transitions);
}
transitions.put(s2, s2); // dummy, non null value
}
// PREMATURE factorize upward
int test(int combinationTestsLoopsNb, boolean skipHighOrderBits) {
Iterator transitionsSetsIterator, transitionsIterator;
State input1, input2, expectedOutput, effectiveOutput;
Map.Entry transition, transitionsSet;
this.failuresNb = 0; // reset
this.failuresNb = 0; // reset
long start = 0;
if (combinationTestsLoopsNb > 1) {
start = System.currentTimeMillis();
}
for (int l = 0; l < combinationTestsLoopsNb ; l++) {
transitionsSetsIterator = this.initializedTransitions.entrySet().iterator();
while (transitionsSetsIterator.hasNext()) {
transitionsSet = (Map.Entry) transitionsSetsIterator.next();
input1 = (State) transitionsSet.getKey();
transitionsIterator = ((Map) transitionsSet.getValue()).
entrySet().iterator();
while (transitionsIterator.hasNext()) {
transition = (Map.Entry) transitionsIterator.next();
input2 = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
effectiveOutput = ((UnconditionalFlowInfoTestHarness) output(
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1),
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2)))
.asState();
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" instead of: " + expectedOutput.printableBitsField);
}
effectiveOutput = ((UnconditionalFlowInfoTestHarness) output(
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input2),
UnconditionalFlowInfoTestHarness.testUnconditionalFlowInfo(input1)))
.asState();
if (effectiveOutput != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" instead of: " + expectedOutput.printableBitsField);
}
}
}
}
if (combinationTestsLoopsNb > 1) {
System.out.println(this.name + "...\t\t" + combinationTestsLoopsNb + "\t" +
(System.currentTimeMillis() - start));
}
// PREMATURE optimize test (extraneous allocations and copies)
// PREMATURE optimize test (extraneous iterations - undup)
if (!skipHighOrderBits) {
UnconditionalFlowInfoTestHarness
zero = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(State.start),
right, left64, right64, right128;
transitionsSetsIterator = this.initializedTransitions.entrySet().iterator();
while (transitionsSetsIterator.hasNext()) {
transitionsSet = (Map.Entry) transitionsSetsIterator.next();
input1 = (State) transitionsSet.getKey();
transitionsIterator = ((Map) transitionsSet.getValue()).
entrySet().iterator();
while (transitionsIterator.hasNext()) {
transition = (Map.Entry) transitionsIterator.next();
input2 = (State) transition.getKey();
expectedOutput = (State) transition.getValue();
left64 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input1, 64);
right = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2);
right64 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2, 64);
right128 = UnconditionalFlowInfoTestHarness.
testUnconditionalFlowInfo(input2, 128);
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(left64, right64)).asState(64)) !=
expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, 64) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right64, left64)).asState(64)) !=
expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, 64) - instead of: " + expectedOutput.printableBitsField);
}
if (input1 == State.start) {
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, right)).asState()) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 128, 1) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(zero, right64)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero, 64) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, right64)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 128, 64) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(zero, right128)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero, 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right64, right128)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input1.printableBitsField +
" + " + input2.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (zero 64, 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right, right128)).asState()) != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (1, zero 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right64, zero)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, zero) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right64, right128)).asState(64)) != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (64, zero 128) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, zero)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (128, zero) - instead of: " + expectedOutput.printableBitsField);
}
if ((effectiveOutput = ((UnconditionalFlowInfoTestHarness)
output(right128, right64)).asState(128)) != expectedOutput) {
fail();
System.out.println("\t\t" + input2.printableBitsField +
" + " + input1.printableBitsField +
" => " + effectiveOutput.printableBitsField +
" (128, zero 64) - instead of: " + expectedOutput.printableBitsField);
}
}
}
}
}
return this.failuresNb;
}
}
}