| /******************************************************************************* |
| * Copyright (c) 2005, 2016 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 |
| * Stephan Herrmann - Contribution for |
| * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" |
| * bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith() |
| * Bug 453635 - [compiler][null] Update NullReferenceImplTests and friends |
| *******************************************************************************/ |
| 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.Arrays; |
| 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; |
| |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public class NullReferenceImplTransformations { |
| public static final Transformation |
| markAsComparedEqualToNonNull = |
| // markAsComparedEqualToNonNull DEFINITION START |
| // start => prot. non null |
| // pot. unknown => pot. nn & prot. nn |
| // pot. non null => pot. nn & prot. nn |
| // pot. nn & pot. un => pot. nn & prot. nn |
| // pot. null => prot. non null |
| // pot. n & pot. un => pot. nn & prot. nn |
| // pot. n & pot. nn => pot. nn & prot. nn |
| // pot. n & pot. nn & pot. un => prot. non null // pot. nn & prot. nn could be better? |
| // def. unknown => def. non null |
| // def. non null => def. non null |
| // pot. nn & prot. nn => pot. nn & prot. nn |
| // def. null => prot. non null |
| // pot. n & prot. n => prot. non null |
| // prot. null => prot. non null |
| // prot. non 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}, |
| {0x1C,0x3C}, |
| {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 |
| // pot. unknown => pot. n & prot. n |
| // pot. non null => prot. null |
| // pot. nn & pot. un => pot. n & prot. n |
| // pot. null => pot. n & prot. n |
| // pot. n & pot. un => pot. n & prot. n |
| // pot. n & pot. nn => pot. n & prot. n |
| // pot. n & pot. nn & pot. un => pot. n & prot. n |
| // def. unknown => def. null |
| // def. non null => prot. null |
| // pot. nn & prot. nn => prot. null |
| // def. null => def. null |
| // pot. n & prot. n => pot. n & prot. n |
| // prot. null => prot. null |
| // prot. non null => prot. 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}, |
| {0x1C,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 |
| // pot. unknown => def. non null |
| // pot. non null => def. non null |
| // pot. nn & pot. un => def. non null |
| // pot. null => def. non null |
| // pot. n & pot. un => def. non null |
| // pot. n & pot. nn => def. non null |
| // pot. n & pot. nn & pot. un => def. non null |
| // def. unknown => def. non null |
| // def. non null => def. non null |
| // pot. nn & prot. nn => def. non null |
| // def. null => def. non null |
| // pot. n & prot. n => def. non null |
| // prot. null => def. non null |
| // prot. non 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}, |
| {0x1C,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 |
| // pot. unknown => def. null |
| // pot. non null => def. null |
| // pot. nn & pot. un => def. null |
| // pot. null => def. null |
| // pot. n & pot. un => def. null |
| // pot. n & pot. nn => def. null |
| // pot. n & pot. nn & pot. un => def. null |
| // def. unknown => def. null |
| // def. non null => def. null |
| // pot. nn & prot. nn => def. null |
| // def. null => def. null |
| // pot. n & prot. n => def. null |
| // prot. null => def. null |
| // prot. non 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}, |
| {0x1C,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 |
| // pot. unknown => def. unknown |
| // pot. non null => def. unknown |
| // pot. nn & pot. un => def. unknown |
| // pot. null => def. unknown |
| // pot. n & pot. un => def. unknown |
| // pot. n & pot. nn => def. unknown |
| // pot. n & pot. nn & pot. un => def. unknown |
| // def. unknown => def. unknown |
| // def. non null => def. unknown |
| // pot. nn & prot. nn => def. unknown |
| // def. null => def. unknown |
| // pot. n & prot. n => def. unknown |
| // prot. null => def. unknown |
| // prot. non 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}, |
| {0x1C,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. un => pot. non null // BOGUS |
| // 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. un => pot. n & pot. nn & 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. 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. un => pot. non null // BOGUS |
| // 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 & pot. un + def. non null => def. non null |
| // pot. n & pot. nn & pot. un + def. null => def. null |
| // pot. n & pot. nn & pot. un + def. unknown => def. unknown |
| // pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & prot. n |
| // pot. n & pot. nn & pot. un + pot. nn & pot. un => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. nn & prot. nn |
| // pot. n & pot. nn & pot. un + pot. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. null => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. unknown => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + prot. non null => pot. nn & prot. nn |
| // pot. n & pot. nn & pot. un + prot. null => pot. n & prot. n |
| // pot. n & pot. nn & pot. un + start => pot. n & pot. nn & pot. un |
| // 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. un => 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 & 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. un => pot. n & pot. nn // should ideally include 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 & 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. un => pot. n & pot. nn & 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. 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. un => pot. non null // should ideally include 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 & 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. un => pot. non null // must include n |
| // 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. un => pot. non null // must include n |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. non null // must include n |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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,0x1C,0x1C}, |
| {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,0x1C,0x08}, |
| {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,0x1C,0x08}, |
| {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,0x1C,0x08}, |
| {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,0x1C,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,0x1C,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,0x1C,0x18}, |
| {0x18,0x24,0x24}, |
| {0x18,0x28,0x28}, |
| {0x18,0x2C,0x2C}, |
| {0x18,0x30,0x30}, |
| {0x18,0x34,0x34}, |
| {0x18,0x38,0x34}, |
| {0x18,0x3C,0x2C}, |
| {0x1C,0x00,0x1C}, |
| {0x1C,0x04,0x1C}, |
| {0x1C,0x08,0x1C}, |
| {0x1C,0x0C,0x1C}, |
| {0x1C,0x10,0x18}, |
| {0x1C,0x14,0x18}, |
| {0x1C,0x18,0x18}, |
| {0x1C,0x1C,0x18}, |
| {0x1C,0x24,0x24}, |
| {0x1C,0x28,0x28}, |
| {0x1C,0x2C,0x2C}, |
| {0x1C,0x30,0x30}, |
| {0x1C,0x34,0x34}, |
| {0x1C,0x38,0x34}, |
| {0x1C,0x3C,0x2C}, |
| {0x24,0x00,0x24}, |
| {0x24,0x04,0x24}, |
| {0x24,0x08,0x24}, |
| {0x24,0x0C,0x24}, |
| {0x24,0x10,0x14}, |
| {0x24,0x14,0x14}, |
| {0x24,0x18,0x18}, |
| {0x24,0x1C,0x08}, |
| {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,0x1C,0x08}, |
| {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,0x1C,0x08}, |
| {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,0x1C,0x1C}, |
| {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,0x1C,0x1C}, |
| {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,0x1C,0x1C}, |
| {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,0x1C,0x1C}, |
| {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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn // should ideally include un |
| // 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 & pot. un + def. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + def. null => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + def. unknown => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. nn & pot. un => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. null => pot. n & pot. nn |
| // pot. n & pot. nn & pot. un + pot. unknown => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + prot. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + prot. null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + start => pot. n & pot. nn & pot. un |
| // 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. un => 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn |
| // 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. un => pot. n & pot. nn // should ideally include un |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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. un => pot. n & pot. nn // un? |
| // 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,0x1C,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,0x1C,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,0x1C,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,0x1C,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,0x1C,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,0x1C,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,0x1C,0x18}, |
| {0x18,0x24,0x18}, |
| {0x18,0x28,0x18}, |
| {0x18,0x2C,0x18}, |
| {0x18,0x30,0x18}, |
| {0x18,0x34,0x18}, |
| {0x18,0x38,0x18}, |
| {0x18,0x3C,0x18}, |
| {0x1C,0x00,0x1C}, |
| {0x1C,0x04,0x1C}, |
| {0x1C,0x08,0x1C}, |
| {0x1C,0x0C,0x1C}, |
| {0x1C,0x10,0x18}, |
| {0x1C,0x14,0x18}, |
| {0x1C,0x18,0x18}, |
| {0x1C,0x1C,0x18}, |
| {0x1C,0x24,0x1C}, |
| {0x1C,0x28,0x1C}, |
| {0x1C,0x2C,0x1C}, |
| {0x1C,0x30,0x18}, |
| {0x1C,0x34,0x18}, |
| {0x1C,0x38,0x1C}, |
| {0x1C,0x3C,0x1C}, |
| {0x24,0x00,0x24}, |
| {0x24,0x04,0x24}, |
| {0x24,0x08,0x24}, |
| {0x24,0x0C,0x24}, |
| {0x24,0x10,0x14}, |
| {0x24,0x14,0x14}, |
| {0x24,0x18,0x18}, |
| {0x24,0x1C,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,0x1C,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,0x1C,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,0x1C,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,0x1C,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,0x1C,0x1C}, |
| {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,0x1C,0x1C}, |
| {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. non null + pot. n & prot. n => pot. n & pot. nn |
| // def. non null + pot. nn & prot. nn => pot. nn & prot. nn |
| // def. non null + prot. non null => pot. nn & prot. nn |
| // def. non null + prot. 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) |
| // def. null + def. null => def. null |
| // def. null + pot. n & prot. n => pot. n & prot. n |
| // def. null + prot. non null => pot. null |
| // def. null + prot. null => pot. n & prot. n |
| // def. unknown + def. non null => pot. nn & pot. un |
| // def. unknown + def. null => pot. n & pot. un // pot. n priv. over def. unknown |
| // def. unknown + def. unknown => def. unknown |
| // def. unknown + pot. n & prot. n => pot. n & pot. un |
| // def. unknown + pot. nn & prot. nn => pot. nn & pot. un |
| // def. unknown + prot. non null => def. unknown // test726 |
| // def. unknown + prot. null => pot. unknown // PREMATURE possibly wrong, but no test case yet |
| // pot. n & pot. nn & pot. un + def. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + def. null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + def. unknown => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + prot. non null => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn & pot. un + prot. null => pot. n & pot. nn & pot. un |
| // 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. un => pot. n & pot. nn & pot. un |
| // pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn |
| // pot. n & pot. nn + pot. n & prot. n => pot. n & pot. nn |
| // pot. n & pot. nn + pot. nn & prot. nn => 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. 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. un => pot. n & pot. nn & 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 & prot. nn => pot. n & pot. nn |
| // pot. n & pot. un + prot. non null => pot. n & pot. un |
| // pot. n & pot. un + prot. null => pot. n & pot. un |
| // pot. n & prot. n + pot. n & prot. n => pot. n & prot. n |
| // pot. n & prot. n + prot. non null => pot. null |
| // pot. n & prot. n + prot. null => 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. un => pot. n & 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. null => pot. n & pot. nn |
| // pot. nn & pot. un + prot. non null => pot. nn & pot. un |
| // pot. nn & pot. un + prot. null => pot. n & pot. nn |
| // pot. nn & prot. nn + def. null => pot. n & pot. nn |
| // pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn |
| // pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn |
| // pot. nn & prot. nn + prot. non null => pot. nn & prot. nn |
| // pot. nn & prot. nn + prot. 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. un => pot. n & 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 + prot. non null => pot. non null |
| // pot. non null + prot. 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. un => pot. n & pot. nn & 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 & prot. nn => pot. n & pot. nn |
| // pot. null + pot. null => pot. null |
| // pot. null + prot. non null => pot. null |
| // pot. null + prot. 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. un => pot. n & pot. nn & pot. un |
| // 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 // PREMATURE possibly wrong, but no test case yet |
| // prot. non null + prot. non null => prot. non null |
| // prot. null + prot. non null => pot. null // PREMATURE use tainted instead |
| // 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. un => pot. n & pot. nn & pot. un |
| // 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,0x1C,0x1C}, |
| {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,0x1C,0x1C}, |
| {0x04,0x24,0x04}, |
| {0x04,0x28,0x0C}, |
| {0x04,0x2C,0x0C}, |
| {0x04,0x30,0x14}, |
| {0x04,0x34,0x14}, |
| {0x04,0x38,0x04}, |
| {0x04,0x3C,0x04}, |
| {0x08,0x08,0x08}, |
| {0x08,0x0C,0x0C}, |
| {0x08,0x10,0x18}, |
| {0x08,0x14,0x18}, |
| {0x08,0x18,0x18}, |
| {0x08,0x1C,0x1C}, |
| {0x08,0x24,0x0C}, |
| {0x08,0x28,0x08}, |
| {0x08,0x2C,0x08}, |
| {0x08,0x30,0x18}, |
| {0x08,0x34,0x18}, |
| {0x08,0x38,0x18}, |
| {0x08,0x3C,0x08}, |
| {0x0C,0x0C,0x0C}, |
| {0x0C,0x10,0x18}, |
| {0x0C,0x14,0x18}, |
| {0x0C,0x18,0x18}, |
| {0x0C,0x1C,0x1C}, |
| {0x0C,0x24,0x0C}, |
| {0x0C,0x28,0x0C}, |
| {0x0C,0x2C,0x0C}, |
| {0x0C,0x30,0x18}, |
| {0x0C,0x34,0x18}, |
| {0x0C,0x38,0x18}, |
| {0x0C,0x3C,0x0C}, |
| {0x10,0x10,0x10}, |
| {0x10,0x14,0x14}, |
| {0x10,0x18,0x18}, |
| {0x10,0x1C,0x1C}, |
| {0x10,0x24,0x14}, |
| {0x10,0x28,0x18}, |
| {0x10,0x2C,0x18}, |
| {0x10,0x30,0x10}, |
| {0x10,0x34,0x10}, |
| {0x10,0x38,0x10}, |
| {0x10,0x3C,0x10}, |
| {0x14,0x14,0x14}, |
| {0x14,0x18,0x18}, |
| {0x14,0x1C,0x1C}, |
| {0x14,0x24,0x14}, |
| {0x14,0x28,0x18}, |
| {0x14,0x2C,0x18}, |
| {0x14,0x30,0x14}, |
| {0x14,0x34,0x14}, |
| {0x14,0x38,0x14}, |
| {0x14,0x3C,0x14}, |
| {0x18,0x18,0x18}, |
| {0x18,0x1C,0x1C}, |
| {0x18,0x24,0x18}, |
| {0x18,0x28,0x18}, |
| {0x18,0x2C,0x18}, |
| {0x18,0x30,0x18}, |
| {0x18,0x34,0x18}, |
| {0x18,0x38,0x18}, |
| {0x18,0x3C,0x18}, |
| {0x1C,0x1C,0x1C}, |
| {0x1C,0x24,0x1C}, |
| {0x1C,0x28,0x1C}, |
| {0x1C,0x2C,0x1C}, |
| {0x1C,0x30,0x1C}, |
| {0x1C,0x34,0x1C}, |
| {0x1C,0x38,0x1C}, |
| {0x1C,0x3C,0x1C}, |
| {0x24,0x24,0x24}, |
| {0x24,0x28,0x0C}, |
| {0x24,0x2C,0x0C}, |
| {0x24,0x30,0x14}, |
| {0x24,0x34,0x14}, |
| {0x24,0x38,0x04}, |
| {0x24,0x3C,0x24}, |
| {0x28,0x28,0x28}, |
| {0x28,0x2C,0x2C}, |
| {0x28,0x30,0x18}, |
| {0x28,0x34,0x18}, |
| {0x28,0x38,0x08}, |
| {0x28,0x3C,0x2C}, |
| {0x2C,0x2C,0x2C}, |
| {0x2C,0x30,0x18}, |
| {0x2C,0x34,0x18}, |
| {0x2C,0x38,0x18}, |
| {0x2C,0x3C,0x2C}, |
| {0x30,0x30,0x30}, |
| {0x30,0x34,0x34}, |
| {0x30,0x38,0x34}, |
| {0x30,0x3C,0x10}, |
| {0x34,0x34,0x34}, |
| {0x34,0x38,0x34}, |
| {0x34,0x3C,0x10}, |
| {0x38,0x38,0x38}, |
| {0x38,0x3C,0x10}, |
| {0x3C,0x3C,0x3C}, |
| // mergedWith INITIALIZER END |
| }) { |
| UnconditionalFlowInfo output(UnconditionalFlowInfo input1, |
| UnconditionalFlowInfo input2) { |
| return input1.copy().mergedWith(input2); |
| } |
| }; |
| public static final Transformation[] transformations = { |
| markAsComparedEqualToNonNull, |
| markAsComparedEqualToNull, |
| markAsDefinitelyNonNull, |
| markAsDefinitelyNull, |
| markAsDefinitelyUnknown, |
| addInitializationsFrom, |
| addPotentialInitializationsFrom, |
| mergedWith |
| }; |
| 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], Integer.valueOf(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; |
| // definitions of two-dim trafos in natural order (by state value): |
| 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; |
| } |
| } |
| 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 = consideredStates.length; |
| State result; |
| // temporary store to support lexical sorting: |
| String[] lines = new String[length * length]; |
| int lCount = 0; |
| for (i = 0; i < length; i++) { |
| for (j = 0; j < length; j++) { |
| StringBuffer line = new StringBuffer(); |
| line.append(tab); |
| line.append("// "); |
| line.append(consideredStates[i].name); |
| line.append(" + "); |
| line.append(consideredStates[j].name); |
| line.append(" => "); |
| line.append( |
| (result = (State) getResult(this.computedTransitions, consideredStates[i], consideredStates[j])).name); |
| if (!result.symbolic || |
| result != getResult(this.initializedTransitions, consideredStates[i], consideredStates[j])) { |
| line.append("\t\t CHECK"); |
| } |
| line.append('\n'); |
| lines[lCount++] = line.toString(); |
| } |
| } |
| Arrays.sort(lines); |
| for (i = 0; i < lCount; i++) { |
| output.write(lines[i]); |
| } |
| } |
| Object getResult(Map transitions, State statei, State statej) { |
| Object res1 = transitions.get(statei); |
| if (res1 instanceof Map) { |
| return ((Map)res1).get(statej); |
| } |
| return null; |
| } |
| 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 = consideredStates.length; |
| State result; |
| // temporary store to support lexical sorting: |
| String[] lines = new String[length * (length +1) / 2 ]; |
| int lCount = 0; |
| for (i = 0; i < length; i++) { |
| for (j = i; j < length; j++) { |
| StringBuffer line = new StringBuffer(); |
| line.append(tab); |
| line.append("// "); |
| line.append(consideredStates[i].name); |
| line.append(" + "); |
| line.append(consideredStates[j].name); |
| line.append(" => "); |
| line.append( |
| (result = (State) getResult(this.computedTransitions, consideredStates[i], consideredStates[j])).name); |
| if (!result.symbolic || |
| result != getResult(this.initializedTransitions, consideredStates[i], consideredStates[j])) { |
| line.append("\t\t CHECK"); |
| } |
| line.append('\n'); |
| lines[lCount++] = line.toString(); |
| } |
| } |
| Arrays.sort(lines); |
| for (i = 0; i < lCount; i++) { |
| output.write(lines[i]); |
| } |
| } |
| Object getResult(Map transitions, State statei, State statej) { |
| Object r = super.getResult(transitions, statei, statej); |
| if (r == null) |
| r = super.getResult(transitions, statej, statei); |
| return r; |
| } |
| 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; |
| } |
| } |
| } |