[LLDB] Fix how ObjCBOOLSummaryProvider deals with BOOL
authorShafik Yaghmour <syaghmour@apple.com>
Fri, 22 Jan 2021 18:04:04 +0000 (10:04 -0800)
committerShafik Yaghmour <syaghmour@apple.com>
Fri, 22 Jan 2021 18:05:24 +0000 (10:05 -0800)
ObjCBOOLSummaryProvider was incorrectly treating BOOL as unsigned and this is now fixed.
Also adding tests for one bit bit-fields of BOOL and unsigned char.

lldb/source/Plugins/Language/ObjC/Cocoa.cpp
lldb/test/API/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
lldb/test/API/functionalities/data-formatter/boolreference/main.mm
lldb/test/API/lang/objc/bitfield_ivars/TestBitfieldIvars.py
lldb/test/API/lang/objc/bitfield_ivars/main.m

index ca4f733..d871d34 100644 (file)
@@ -1035,7 +1035,7 @@ bool lldb_private::formatters::ObjCBOOLSummaryProvider(
     if (!real_guy_sp)
       return false;
   }
-  uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
+  int8_t value = (real_guy_sp->GetValueAsSigned(0) & 0xFF);
   switch (value) {
   case 0:
     stream.Printf("NO");
@@ -1044,7 +1044,7 @@ bool lldb_private::formatters::ObjCBOOLSummaryProvider(
     stream.Printf("YES");
     break;
   default:
-    stream.Printf("%u", value);
+    stream.Printf("%d", value);
     break;
   }
   return true;
index 7435409..815a8ab 100644 (file)
@@ -75,3 +75,12 @@ class DataFormatterBoolRefPtr(TestBase):
                     substrs=['NO'])
         if not(isArm):
             self.expect('frame variable unset', substrs=['12'])
+
+        self.expect_expr('myField', result_type="BoolBitFields",
+                 result_children=[
+                     ValueCheck(name="fieldOne", summary="NO"),
+                     ValueCheck(name="fieldTwo", summary="-1"),
+                     ValueCheck(name="fieldThree", summary="NO"),
+                     ValueCheck(name="fieldFour", summary="NO"),
+                     ValueCheck(name="fieldFive", summary="-1")
+                 ])
index ce25c0b..1218492 100644 (file)
@@ -1,12 +1,20 @@
 #import <Foundation/Foundation.h>
 
+typedef struct {
+    BOOL fieldOne : 1;
+    BOOL fieldTwo : 1;
+    BOOL fieldThree : 1;
+    BOOL fieldFour : 1;
+    BOOL fieldFive : 1;
+} BoolBitFields;
+
 int main (int argc, const char * argv[])
 {
-    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
        BOOL yes  = YES;
        BOOL no = NO;
-    BOOL unset = 12;
+  BOOL unset = 12;
        
        BOOL &yes_ref = yes;
        BOOL &no_ref = no;
@@ -16,6 +24,10 @@ int main (int argc, const char * argv[])
        BOOL* no_ptr = &no;
        BOOL* unset_ptr = &unset;
 
+  BoolBitFields myField = {0};
+  myField.fieldTwo = YES;
+  myField.fieldFive = YES;
+
     [pool drain];// Set break point at this line.
     return 0;
 }
index 644dca5..4e7590d 100644 (file)
@@ -25,6 +25,15 @@ class TestBitfieldIvars(TestBase):
                                              'field2 =', '3',
                                              'field3 =', '4'])
 
+        self.expect_expr('myField', result_type="UCBitFields",
+                 result_children=[
+                     ValueCheck(name="fieldOne", value="'\\0'"),
+                     ValueCheck(name="fieldTwo", value="'\\x01'"),
+                     ValueCheck(name="fieldThree", value="'\\0'"),
+                     ValueCheck(name="fieldFour", value="'\\0'"),
+                     ValueCheck(name="fieldFive", value="'\\x01'")
+                 ])
+
     # This test is meant to be xfailed, but running the test triggers an ASan
     # issue, so it must be skipped for now.
     @skipIf
index 841464d..ce0ca31 100644 (file)
@@ -1,5 +1,13 @@
 #import <Foundation/Foundation.h>
 
+typedef struct {
+    unsigned char fieldOne : 1;
+    unsigned char fieldTwo : 1;
+    unsigned char fieldThree : 1;
+    unsigned char fieldFour : 1;
+    unsigned char fieldFive : 1;
+} UCBitFields;
+
 @interface HasBitfield : NSObject {
 @public
     unsigned field1 : 1;
@@ -59,6 +67,10 @@ int main(int argc, const char * argv[]) {
     hb2->field2 = 3;
     hb2->field3 = 4;
 
+    UCBitFields myField = {0};
+    myField.fieldTwo = 1;
+    myField.fieldFive = 1;
+
     return 0; // break here
 }