Author: spyffe Date: Fri Aug 26 13:12:39 2016 New Revision: 279850 URL: http://llvm.org/viewvc/llvm-project?rev=279850&view=rev Log: Don't crash when trying to capture persistent variables in a block.
Reports an error instead. We can fix this later to make persistent variables work, but right now we hit an LLVM assertion if we get this wrong. <rdar://problem/27770298> Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py?rev=279850&r1=279849&r2=279850&view=diff ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py (original) +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py Fri Aug 26 13:12:39 2016 @@ -57,8 +57,10 @@ class BlocksTestCase(TestBase): self.launch_common() self.runCmd("expression int (^$add)(int, int) = ^int(int a, int b) { return a + b; };") - self.expect("expression $add(2,3)", VARIABLES_DISPLAYED_CORRECTLY, substrs = [" = 5"]) + + self.runCmd("expression int $a = 3") + self.expect("expression int (^$addA)(int) = ^int(int b) { return $a + b; };", "Proper error is reported on capture", error=True) def wait_for_breakpoint(self): if self.is_started == False: Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=279850&r1=279849&r2=279850&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Fri Aug 26 13:12:39 2016 @@ -885,7 +885,7 @@ ClangExpressionParser::PrepareForExecuti Process *process = exe_ctx.GetProcessPtr(); - if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel) + if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel && ir_can_run) { lldb_private::Error interpret_error; Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp?rev=279850&r1=279849&r2=279850&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp Fri Aug 26 13:12:39 2016 @@ -552,7 +552,7 @@ IRForTarget::RewriteObjCConstString (llv llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function))); }); - if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder)) + if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, nullptr)) { if (log) log->PutCString("Couldn't replace the NSString with the result of the call"); @@ -1602,8 +1602,10 @@ IRForTarget::RemoveGuards(BasicBlock &ba // This function does not report errors; its callers are responsible. bool IRForTarget::UnfoldConstant(Constant *old_constant, + llvm::Function *llvm_function, FunctionValueCache &value_maker, - FunctionValueCache &entry_instruction_finder) + FunctionValueCache &entry_instruction_finder, + lldb_private::Stream *error_stream) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1647,7 +1649,7 @@ IRForTarget::UnfoldConstant(Constant *ol llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); }); - if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder)) + if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker, entry_instruction_finder, error_stream)) return false; } break; @@ -1685,7 +1687,7 @@ IRForTarget::UnfoldConstant(Constant *ol return GetElementPtrInst::Create(nullptr, ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); }); - if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder)) + if (!UnfoldConstant(constant_expr, llvm_function, get_element_pointer_maker, entry_instruction_finder, error_stream)) return false; } break; @@ -1702,6 +1704,14 @@ IRForTarget::UnfoldConstant(Constant *ol { if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) { + if (llvm_function && inst->getParent()->getParent() != llvm_function) + { + if (error_stream) + { + error_stream->PutCString("error: Capturing non-local variables in expressions is unsupported.\n"); + } + return false; + } inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent())); } else @@ -1896,10 +1906,21 @@ IRForTarget::ReplaceVariables (Function if (Constant *constant = dyn_cast<Constant>(value)) { - UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder); + if (!UnfoldConstant(constant, &llvm_function, body_result_maker, m_entry_instruction_finder, m_error_stream)) + { + return false; + } } else if (Instruction *instruction = dyn_cast<Instruction>(value)) { + if (instruction->getParent()->getParent() != &llvm_function) + { + if (m_error_stream) + { + m_error_stream->PutCString("error: Capturing non-local variables in expressions is unsupported.\n"); + } + return false; + } value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent())); } else Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h?rev=279850&r1=279849&r2=279850&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h Fri Aug 26 13:12:39 2016 @@ -611,9 +611,11 @@ private: FunctionValueCache m_entry_instruction_finder; static bool - UnfoldConstant (llvm::Constant *old_constant, + UnfoldConstant (llvm::Constant *old_constant, + llvm::Function *llvm_function, FunctionValueCache &value_maker, - FunctionValueCache &entry_instruction_finder); + FunctionValueCache &entry_instruction_finder, + lldb_private::Stream *error_stream); //------------------------------------------------------------------ /// Construct a reference to m_reloc_placeholder with a given type _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits