From 8c62daf250020c76a78c54c2efc321d61c84f411 Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Fri, 12 Feb 2016 21:16:58 +0000 Subject: [PATCH] IRInterpreter now recognizes expressions with constants it doesn't handle. If an instruction has a constant that IRInterpreter doesn't know how to deal with (say, an array constant, because we can't materialize it to APInt) then we used to ignore that and only fail during expression execution. This is annoying because if IRInterpreter had just returned false from CanInterpret(), the JIT would have been used. Now the IRInterpreter checks constants as part of CanInterpret(), so this should hopefully no longer be an issue. llvm-svn: 260735 --- lldb/source/Expression/IRInterpreter.cpp | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 29c6742..2b9bb7c 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -465,6 +465,45 @@ static const char *memory_read_error = "Interpreter couldn't read static const char *infinite_loop_error = "Interpreter ran for too many cycles"; //static const char *bad_result_error = "Result of expression is in bad memory"; +static bool +CanResolveConstant (llvm::Constant *constant) +{ + switch (constant->getValueID()) + { + default: + return false; + case Value::ConstantIntVal: + case Value::ConstantFPVal: + return true; + case Value::ConstantExprVal: + if (const ConstantExpr *constant_expr = dyn_cast(constant)) + { + switch (constant_expr->getOpcode()) + { + default: + return false; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + case Instruction::BitCast: + return CanResolveConstant(constant_expr->getOperand(0)); + case Instruction::GetElementPtr: + { + ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); + Constant *base = dyn_cast(*op_cursor); + if (!base) + return false; + + return CanResolveConstant(base); + } + } + } else { + return false; + } + case Value::ConstantPointerNullVal: + return true; + } +} + bool IRInterpreter::CanInterpret (llvm::Module &module, llvm::Function &function, @@ -611,6 +650,17 @@ IRInterpreter::CanInterpret (llvm::Module &module, return false; } } + + if (Constant *constant = llvm::dyn_cast(operand)) + { + if (!CanResolveConstant(constant)) + { + if (log) + log->Printf("Unsupported constant: %s", PrintValue(constant).c_str()); + error.SetErrorString(unsupported_operand_error); + return false; + } + } } } -- 2.7.4