From: Sean Callanan Date: Fri, 26 Aug 2016 18:12:39 +0000 (+0000) Subject: Don't crash when trying to capture persistent variables in a block. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fc670cf6d0cea44f3a5d96baaa4755c07b904987;p=platform%2Fupstream%2Fllvm.git 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. llvm-svn: 279850 --- diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py b/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py index 0cc9456..e31b56c 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py +++ b/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py @@ -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: diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index d1a3c0d..bb5c8a0 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -885,7 +885,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, 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; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 12ba7e3..7666f07 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -552,7 +552,7 @@ IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str, llvm::cast(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 &basic_block) // 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 *old_constant, llvm::cast(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 *old_constant, return GetElementPtrInst::Create(nullptr, ptr, indices, "", llvm::cast(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 *old_constant, { if (Instruction *inst = llvm::dyn_cast(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 &llvm_function) if (Constant *constant = dyn_cast(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(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 diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h index 0f95f67..c006338 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -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