Index: lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py =================================================================== --- lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py +++ lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py @@ -40,6 +40,29 @@ self.runCmd("run", RUN_SUCCEEDED) + class Variable: + def __init__(self, uid, type, value): + self.name = "$i_" + str(uid) + "_" + type.replace(" ", "_") + self.value = value + self.type = type + self.decl_expr = type + " " + self.name + " = " + str(self.value) + self.unsigned_type = "unsigned" in type + + class Operator: + def __init__(self, name): + self.name = name + + def can_handle_operands(self, lhs, rhs): + """True iff this operator can handle the variables as operands.""" + if self.name in ['<<', '>>']: + # Shifting negative values, shifting by negative values and + # shifting by too large values will make this test fail. + if lhs.value <= 0 and not lhs.unsigned_type: + return False + if rhs.value <= 0 or rhs.value >= 32: + return False + return True + @add_test_categories(['pyapi']) # getpid() is POSIX, among other problems, see bug @expectedFailureAll( @@ -50,35 +73,73 @@ oslist=['linux'], archs=['arm'], bugnumber="llvm.org/pr27868") - def test_ir_interpreter(self): + def test_ir_interpreter_int_ops(self): self.build_and_run() + # Normal expression options we use for JITed expressions. options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeC_plus_plus) - set_up_expressions = ["int $i = 9", "int $j = 3", "int $k = 5"] - - expressions = ["$i + $j", - "$i - $j", - "$i * $j", - "$i / $j", - "$i % $k", - "$i << $j", - "$i & $j", - "$i | $j", - "$i ^ $j"] - - for expression in set_up_expressions: - self.frame().EvaluateExpression(expression, options) - - for expression in expressions: + # Expression options that prevent that we use the JIT. + nojit_options = lldb.SBExpressionOptions() + nojit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus) + nojit_options.SetAllowJIT(False) + + # List of operators the interpreter supports and we want to test. + operators = ['+', '-', '*', '%', '/', + '<<', '>>', '&', '|', '^', + '>', '<', '>=', '<=', '!=', '=='] + operator_list = [] + for opname in operators: + operator_list.append(self.Operator(opname)) + + # Variable types that should be tested with the operators. + types_to_test = ['int', 'unsigned int'] + + # Values these variables can have. + values_to_test = [255, 256, -1, 0, 1, 255, 256] + + # Id for every variable to give them unique names. + uid = 0 + # Define a variable for every type and for every value in LLDB. + variable_list = [] + for t in types_to_test: + for value in values_to_test: + v = self.Variable(uid, t, value) + variable_list.append(v) + interp_result = self.frame().EvaluateExpression( + v.decl_expr, nojit_options).GetValueAsUnsigned() + uid += 1 + + # Create a list of expressions that use every operator. + exprs_to_run = [] + for op in operator_list: + # Try all combinations of variables with the operator. + for var1 in variable_list: + for var2 in variable_list: + if not op.can_handle_operands(var1, var2): + continue + # Create an expression using the operator. + expr = var1.name + " " + op.name + " " + var2.name + # Resolve the variable values and add that as a comment + # to the expression. This will be shown when the test fails. + expr += " // " + str(var1.value) + " " + op.name + " " + str(var2.value) + exprs_to_run.append(expr) + + # Make sure we actually did generate a list of expressions. + assert len(exprs_to_run) != 0 + for expression in exprs_to_run: interp_expression = expression + # We call 'getpid()' as a trick to force the expression to JITed. + # FIXME: Find a non-hacky way to tell LLDB to enforce this. jit_expression = "(int)getpid(); " + expression + # Run the expression in the interpreter and in the JIT. Both + # should produce the same result. interp_result = self.frame().EvaluateExpression( - interp_expression, options).GetValueAsSigned() + interp_expression, nojit_options).GetValueAsUnsigned() jit_result = self.frame().EvaluateExpression( - jit_expression, options).GetValueAsSigned() + jit_expression, options).GetValueAsUnsigned() self.assertEqual( interp_result,