public void NullExceptionArithmetic(VarType type, BooleanTestType testType, string operatorToTest, int v1, int?v2, int v3) { RunTest("!=", InferError.None); RunTest("==", InferError.NULL_DEREFERENCE); void RunTest(string comparisonOperator, InferError expectedError) { var testCode = InitVars( state: TestClassState.Null, firstLocalVarType: type, secondLocalVarType: type, firstLocalVarValue: v1.ToString(), secondLocalVarValue: v2?.ToString()) + GenerateSingleComparisonIfCondition( testType, operatorToTest, secondOperator: comparisonOperator, valueToBeComparedAgainst: v3.ToString()) + DerefObject(VarName.Tc); TestRunManager.Run(testCode, GetString(expectedError)); } }
/// <summary> /// Helper method for generating boolean formula test code for validating that the /// translation of an operator is correctly understood by Infer. /// It handles three types of formulae, where v1, v2, valueToBeComparedAgainst are /// primitive values: /// 1. Validate unary operator: op1 x op2 y, i.e. for operator "-", -3 == -3 /// 2. Validate binary operator: (x op1 y) op2 y, i.e. for operator "+", (3 + 5) == 8 /// 3. Validate comparison operator: x op1 y, i.e. for operator ">", 4 > 3 /// In cases (1) and (2), both op2 and valueToBeComparedAgainst should be provided. /// </summary> /// <param name="type">The expression type, among the three options.</param> /// <param name="firstOperator">The string representation of the first operator.</param> /// <param name="secondOperator">The string representation of the second operator.</param> /// <param name="valueToBeComparedAgainst">For cases (1) and (2), this is the value /// against which the expression is compared. For case 3, it should not be /// provided.</param> public static string GenerateSingleComparisonIfCondition( BooleanTestType type, string firstOperator, string secondOperator = null, string valueToBeComparedAgainst = null) { string booleanFormula; switch (type) { case BooleanTestType.Binary: if (secondOperator == null || valueToBeComparedAgainst == null) { throw new ArgumentException( "op2 and valueToBeComparedAgainst must be provided."); } booleanFormula = $@"({GetString(VarName.FirstLocal)} {firstOperator} {GetString(VarName.SecondLocal)}) {secondOperator} {valueToBeComparedAgainst}"; break; case BooleanTestType.Comparison: booleanFormula = $@"{GetString(VarName.FirstLocal)} {firstOperator} {GetString(VarName.SecondLocal)}"; break; case BooleanTestType.Unary: if (secondOperator == null || valueToBeComparedAgainst == null) { throw new ArgumentException( "op2 and valueToBeComparedAgainst must be provided."); } booleanFormula = $@"{firstOperator} {GetString(VarName.FirstLocal)} {secondOperator} {valueToBeComparedAgainst}"; break; default: throw new NotImplementedException("Unhandled BooleanTestType"); } return("if (" + booleanFormula + ")"); }