[Lldb-commits] [lldb] afb446e - [lldb] Constant-resolve operands to `getelementptr`

Andy Yankovsky via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 9 08:39:51 PST 2022


Author: Andy Yankovsky
Date: 2022-02-09T17:38:38+01:00
New Revision: afb446e8a61de4a41504a71f61a4b1d93ce22716

URL: https://github.com/llvm/llvm-project/commit/afb446e8a61de4a41504a71f61a4b1d93ce22716
DIFF: https://github.com/llvm/llvm-project/commit/afb446e8a61de4a41504a71f61a4b1d93ce22716.diff

LOG: [lldb] Constant-resolve operands to `getelementptr`

Operands to `getelementptr` can be constants or constant expressions. Check
that all operands can be constant-resolved and resolve them during the
evaluation. If some operands can't be resolved as constants -- the expression
evaluation will fallback to JIT.

Fixes: https://bugs.llvm.org/show_bug.cgi?id=52449

Reviewed By: #lldb, shafik

Differential Revision: https://reviews.llvm.org/D113498

Added: 
    

Modified: 
    lldb/source/Expression/IRInterpreter.cpp
    lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index 21348be1578ff..2ad51d0e84027 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -285,9 +285,11 @@ class InterpreterStackFrame {
             return true; // no offset to apply!
 
           SmallVector<Value *, 8> indices(op_cursor, op_end);
-
           Type *src_elem_ty =
               cast<GEPOperator>(constant_expr)->getSourceElementType();
+
+          // DataLayout::getIndexedOffsetInType assumes the indices are
+          // instances of ConstantInt.
           uint64_t offset =
               m_target_data.getIndexedOffsetInType(src_elem_ty, indices);
 
@@ -466,12 +468,20 @@ static bool CanResolveConstant(llvm::Constant *constant) {
       case Instruction::BitCast:
         return CanResolveConstant(constant_expr->getOperand(0));
       case Instruction::GetElementPtr: {
+        // Check that the base can be constant-resolved.
         ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
         Constant *base = dyn_cast<Constant>(*op_cursor);
-        if (!base)
+        if (!base || !CanResolveConstant(base))
           return false;
 
-        return CanResolveConstant(base);
+        // Check that all other operands are just ConstantInt.
+        for (Value *op : make_range(constant_expr->op_begin() + 1,
+                                    constant_expr->op_end())) {
+          ConstantInt *constant_int = dyn_cast<ConstantInt>(op);
+          if (!constant_int)
+            return false;
+        }
+        return true;
       }
       }
     } else {

diff  --git a/lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py b/lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py
index 07ec5c52ea4c7..503e0d1341566 100644
--- a/lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py
+++ b/lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py
@@ -41,3 +41,31 @@ def test_access_without_scope(self):
         self.createTestTarget()
         self.expect("expression s_c", error=True,
                     startstr="error: use of undeclared identifier 's_d'")
+
+    def test_no_crash_in_IR_arithmetic(self):
+        """
+        Test that LLDB doesn't crash on evaluating specific expression involving
+        pointer arithmetic and taking the address of a static class member.
+        See https://bugs.llvm.org/show_bug.cgi?id=52449
+        """
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "// stop in main", lldb.SBFileSpec("main.cpp"))
+
+        # This expression contains the following IR code:
+        # ... i64 ptrtoint (i32* @_ZN1A3s_cE to i64)) ...
+        expr = "(int*)100 + (long long)(&A::s_c)"
+
+        # The IR interpreter doesn't support non-const operands to the
+        # `GetElementPtr` IR instruction, so verify that it correctly fails to
+        # evaluate expression.
+        opts = lldb.SBExpressionOptions()
+        opts.SetAllowJIT(False)
+        value = self.target().EvaluateExpression(expr, opts)
+        self.assertTrue(value.GetError().Fail())
+        self.assertIn(
+            "Can't evaluate the expression without a running target",
+            value.GetError().GetCString())
+
+        # Evaluating the expression via JIT should work fine.
+        value = self.target().EvaluateExpression(expr)
+        self.assertSuccess(value.GetError())


        


More information about the lldb-commits mailing list