Skip to content

[lldb] Fix AppleObjCDeclVendor for classes which have no methods #145452

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

Conversation

kastiglione
Copy link
Contributor

Fix the rare case where an ObjC class has ivars but no methods. The fix is to not early
return when a class has no method list.

Fix the rare case where an ObjC class has ivars but no methods. The fix is to not early
return when a class has no method list.
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-lldb

Author: Dave Lee (kastiglione)

Changes

Fix the rare case where an ObjC class has ivars but no methods. The fix is to not early
return when a class has no method list.


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

6 Files Affected:

  • (modified) lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp (+3-4)
  • (added) lldb/test/API/lang/objc/class-without-methods/Makefile (+5)
  • (added) lldb/test/API/lang/objc/class-without-methods/Point.h (+8)
  • (added) lldb/test/API/lang/objc/class-without-methods/Point.m (+4)
  • (added) lldb/test/API/lang/objc/class-without-methods/TestObjCClassWithoutMethods.py (+11)
  • (added) lldb/test/API/lang/objc/class-without-methods/main.m (+9)
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index dac93931bab1b..1c120fcf2c356 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -552,10 +552,9 @@ bool ClassDescriptorV2::Describe(
     } else {
       std::optional<method_list_t> base_method_list =
           GetMethodList(process, class_ro->m_baseMethods_ptr);
-      if (!base_method_list)
-        return false;
-      if (!ProcessMethodList(instance_method_func, *base_method_list))
-        return false;
+      if (base_method_list)
+        if (!ProcessMethodList(instance_method_func, *base_method_list))
+          return false;
     }
   }
 
diff --git a/lldb/test/API/lang/objc/class-without-methods/Makefile b/lldb/test/API/lang/objc/class-without-methods/Makefile
new file mode 100644
index 0000000000000..f6f336c01bbc5
--- /dev/null
+++ b/lldb/test/API/lang/objc/class-without-methods/Makefile
@@ -0,0 +1,5 @@
+OBJC_SOURCES := Point.m main.m
+include Makefile.rules
+
+# Only objc metadata, no debug info, for Point.m
+Point.o: CFLAGS_EXTRAS += -g0
diff --git a/lldb/test/API/lang/objc/class-without-methods/Point.h b/lldb/test/API/lang/objc/class-without-methods/Point.h
new file mode 100644
index 0000000000000..85c0cd6c895b3
--- /dev/null
+++ b/lldb/test/API/lang/objc/class-without-methods/Point.h
@@ -0,0 +1,8 @@
+#import <objc/NSObject.h>
+
+@interface Point : NSObject {
+@public
+  float _x;
+  float _y;
+}
+@end
diff --git a/lldb/test/API/lang/objc/class-without-methods/Point.m b/lldb/test/API/lang/objc/class-without-methods/Point.m
new file mode 100644
index 0000000000000..eb5888e5b599f
--- /dev/null
+++ b/lldb/test/API/lang/objc/class-without-methods/Point.m
@@ -0,0 +1,4 @@
+#import "Point.h"
+
+@implementation Point
+@end
diff --git a/lldb/test/API/lang/objc/class-without-methods/TestObjCClassWithoutMethods.py b/lldb/test/API/lang/objc/class-without-methods/TestObjCClassWithoutMethods.py
new file mode 100644
index 0000000000000..587f22dedadf7
--- /dev/null
+++ b/lldb/test/API/lang/objc/class-without-methods/TestObjCClassWithoutMethods.py
@@ -0,0 +1,11 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    def test(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+        self.expect("frame var -P1 p", substrs=["_x = 11", "_y = 22"])
diff --git a/lldb/test/API/lang/objc/class-without-methods/main.m b/lldb/test/API/lang/objc/class-without-methods/main.m
new file mode 100644
index 0000000000000..f3241f46bbe5f
--- /dev/null
+++ b/lldb/test/API/lang/objc/class-without-methods/main.m
@@ -0,0 +1,9 @@
+#import "Point.h"
+
+int main() {
+  Point *p = [Point new];
+  p->_x = 11;
+  p->_y = 22;
+  // break here
+  return 0;
+}

This ensures the debug info in main.o does not contain the ivars for Point.
@kastiglione kastiglione merged commit 23b0564 into llvm:main Jun 24, 2025
7 checks passed
@kastiglione kastiglione deleted the lldb-Fix-AppleObjCDeclVendor-for-classes-which-have-no-methods branch June 24, 2025 17:58
DrSergei pushed a commit to DrSergei/llvm-project that referenced this pull request Jun 24, 2025
…m#145452)

Fix the rare case where an ObjC class has ivars but no methods. The fix is to not early
return when a class has no method list.
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
…m#145452)

Fix the rare case where an ObjC class has ivars but no methods. The fix is to not early
return when a class has no method list.
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