Skip to content

[lldb] Remove Function null checks in Block.cpp #137611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2025
Merged

Conversation

labath
Copy link
Collaborator

@labath labath commented Apr 28, 2025

As of #117683, Blocks are always enclosed in a function, so these checks never fail. We can't change the signature of
CalculateSymbolContextFunction as it's an abstract function (and some of its implementations can return nullptr), but we can create a different function that we can call when we know we're dealing with a block.

As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
@labath labath requested a review from DavidSpickett April 28, 2025 10:12
@labath labath requested a review from JDevlieghere as a code owner April 28, 2025 10:12
@llvmbot llvmbot added the lldb label Apr 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 28, 2025

@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)

Changes

As of #117683, Blocks are always enclosed in a function, so these checks never fail. We can't change the signature of
CalculateSymbolContextFunction as it's an abstract function (and some of its implementations can return nullptr), but we can create a different function that we can call when we know we're dealing with a block.


Full diff: https://github.com/llvm/llvm-project/pull/137611.diff

2 Files Affected:

  • (modified) lldb/include/lldb/Symbol/Block.h (+2)
  • (modified) lldb/source/Symbol/Block.cpp (+42-48)
diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h
index d0063f132cc0f..501c912b674ac 100644
--- a/lldb/include/lldb/Symbol/Block.h
+++ b/lldb/include/lldb/Symbol/Block.h
@@ -78,6 +78,8 @@ class Block : public UserID, public SymbolContextScope {
 
   Block *CalculateSymbolContextBlock() override;
 
+  Function &GetFunction();
+
   /// Check if an offset is in one of the block offset ranges.
   ///
   /// \param[in] range_offset
diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp
index 6ecc988d7a5a9..9d01293ea64e0 100644
--- a/lldb/source/Symbol/Block.cpp
+++ b/lldb/source/Symbol/Block.cpp
@@ -153,10 +153,16 @@ Function *Block::CalculateSymbolContextFunction() {
 
 Block *Block::CalculateSymbolContextBlock() { return this; }
 
-void Block::DumpSymbolContext(Stream *s) {
+Function &Block::GetFunction() {
+  // Blocks always have an enclosing function because their parent is either a
+  // function or a block (which has a parent, inductively).
   Function *function = CalculateSymbolContextFunction();
-  if (function)
-    function->DumpSymbolContext(s);
+  assert(function);
+  return *function;
+}
+
+void Block::DumpSymbolContext(Stream *s) {
+  GetFunction().DumpSymbolContext(s);
   s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
 }
 
@@ -241,20 +247,17 @@ bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
 
 bool Block::GetRangeContainingAddress(const Address &addr,
                                       AddressRange &range) {
-  Function *function = CalculateSymbolContextFunction();
-  if (function) {
-    if (uint32_t idx = GetRangeIndexContainingAddress(addr);
-        idx != UINT32_MAX) {
-      const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
-      assert(range_ptr);
-
-      Address func_addr = function->GetAddress();
-      range.GetBaseAddress() =
-          Address(func_addr.GetFileAddress() + range_ptr->GetRangeBase(),
-                  func_addr.GetModule()->GetSectionList());
-      range.SetByteSize(range_ptr->GetByteSize());
-      return true;
-    }
+  Function &function = GetFunction();
+  if (uint32_t idx = GetRangeIndexContainingAddress(addr); idx != UINT32_MAX) {
+    const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
+    assert(range_ptr);
+
+    Address func_addr = function.GetAddress();
+    range.GetBaseAddress() =
+        Address(func_addr.GetFileAddress() + range_ptr->GetRangeBase(),
+                func_addr.GetModule()->GetSectionList());
+    range.SetByteSize(range_ptr->GetByteSize());
+    return true;
   }
   range.Clear();
   return false;
@@ -269,11 +272,9 @@ bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
 }
 
 uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
-  Function *function = CalculateSymbolContextFunction();
-  if (!function)
-    return UINT32_MAX;
+  Function &function = GetFunction();
 
-  const Address &func_addr = function->GetAddress();
+  const Address &func_addr = function.GetAddress();
   if (addr.GetModule() != func_addr.GetModule())
     return UINT32_MAX;
 
@@ -283,29 +284,25 @@ uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
 }
 
 bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
-  if (range_idx < m_ranges.GetSize()) {
-    Function *function = CalculateSymbolContextFunction();
-    if (function) {
-      const Range &vm_range = m_ranges.GetEntryRef(range_idx);
-      range.GetBaseAddress() = function->GetAddress();
-      range.GetBaseAddress().Slide(vm_range.GetRangeBase());
-      range.SetByteSize(vm_range.GetByteSize());
-      return true;
-    }
-  }
-  return false;
+  if (range_idx >= m_ranges.GetSize())
+    return false;
+
+  Function &function = GetFunction();
+  const Range &vm_range = m_ranges.GetEntryRef(range_idx);
+  range.GetBaseAddress() = function.GetAddress();
+  range.GetBaseAddress().Slide(vm_range.GetRangeBase());
+  range.SetByteSize(vm_range.GetByteSize());
+  return true;
 }
 
 AddressRanges Block::GetRanges() {
   AddressRanges ranges;
-  Function *function = CalculateSymbolContextFunction();
-  if (!function)
-    return ranges;
+  Function &function = GetFunction();
   for (size_t i = 0, e = m_ranges.GetSize(); i < e; ++i) {
     ranges.emplace_back();
     auto &range = ranges.back();
     const Range &vm_range = m_ranges.GetEntryRef(i);
-    range.GetBaseAddress() = function->GetAddress();
+    range.GetBaseAddress() = function.GetAddress();
     range.GetBaseAddress().Slide(vm_range.GetRangeBase());
     range.SetByteSize(vm_range.GetByteSize());
   }
@@ -316,13 +313,10 @@ bool Block::GetStartAddress(Address &addr) {
   if (m_ranges.IsEmpty())
     return false;
 
-  Function *function = CalculateSymbolContextFunction();
-  if (function) {
-    addr = function->GetAddress();
-    addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
-    return true;
-  }
-  return false;
+  Function &function = GetFunction();
+  addr = function.GetAddress();
+  addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
+  return true;
 }
 
 void Block::FinalizeRanges() {
@@ -336,11 +330,11 @@ void Block::AddRange(const Range &range) {
     Log *log = GetLog(LLDBLog::Symbols);
     if (log) {
       ModuleSP module_sp(m_parent_scope.CalculateSymbolContextModule());
-      Function *function = m_parent_scope.CalculateSymbolContextFunction();
-      const addr_t function_file_addr = function->GetAddress().GetFileAddress();
+      Function &function = GetFunction();
+      const addr_t function_file_addr = function.GetAddress().GetFileAddress();
       const addr_t block_start_addr = function_file_addr + range.GetRangeBase();
       const addr_t block_end_addr = function_file_addr + range.GetRangeEnd();
-      Type *func_type = function->GetType();
+      Type *func_type = function.GetType();
 
       const Declaration &func_decl = func_type->GetDeclaration();
       if (func_decl.GetLine()) {
@@ -351,7 +345,7 @@ void Block::AddRange(const Range &range) {
                   "} in function {0x%8.8" PRIx64 "} from %s",
                   func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
                   GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
-                  block_end_addr, parent_block->GetID(), function->GetID(),
+                  block_end_addr, parent_block->GetID(), function.GetID(),
                   module_sp->GetFileSpec().GetPath().c_str());
       } else {
         LLDB_LOGF(log,
@@ -360,7 +354,7 @@ void Block::AddRange(const Range &range) {
                   ") which is not contained in parent block {0x%8.8" PRIx64
                   "} in function {0x%8.8" PRIx64 "} from %s",
                   GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
-                  block_end_addr, parent_block->GetID(), function->GetID(),
+                  block_end_addr, parent_block->GetID(), function.GetID(),
                   module_sp->GetFileSpec().GetPath().c_str());
       }
     }

@DavidSpickett
Copy link
Collaborator

We can't change the signature of CalculateSymbolContextFunction as it's an abstract function (and some of its implementations can return nullptr)

By which you mean, because there are still use cases for CalculateSymbolContextFunction to return nullptr, so it must remain.

As opposed to how I first read this which was, because it was exposed in some ABI we had to maintain.

@labath
Copy link
Collaborator Author

labath commented Apr 28, 2025

We can't change the signature of CalculateSymbolContextFunction as it's an abstract function (and some of its implementations can return nullptr)

By which you mean, because there are still use cases for CalculateSymbolContextFunction to return nullptr, so it must remain.

Correct. CalculateSymbolContextFunction is defined in the SymbolContextScope class, which is an interface for "things that can turn themselves into other things". So e.g. CompileUnit::CalculateSymbolContextFunction returns null because there's no mapping from a compile unit to a function (but there is a mapping from a function to a compile unit, so we could potentially make a non-fallible version of Function::CalculateCompileUnit).

Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@labath labath merged commit 679cc0a into llvm:main Apr 29, 2025
12 checks passed
@labath labath deleted the block-fn branch April 29, 2025 06:20
gizmondo pushed a commit to gizmondo/llvm-project that referenced this pull request Apr 29, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
As of llvm#117683, Blocks are always enclosed in a function, so these checks
never fail. We can't change the signature of
`CalculateSymbolContextFunction` as it's an abstract function (and some
of its implementations can return nullptr), but we can create a
different function that we can call when we know we're dealing with a
block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants