[Lldb-commits] [lldb] r279850 - Don't crash when trying to capture persistent variables in a block.

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Fri Aug 26 11:12:40 PDT 2016


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




More information about the lldb-commits mailing list