From 5814255e1a7d2e90580d6df457ddd13b1cd156cb Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 6 Jul 2020 16:31:56 +0200 Subject: [PATCH] [lldb] Always round down in NSDate's formatter to match NSDate's builtin format Summary: When printing an NSDate (for example with `NSLog` or `po`) the seconds value is always rounded down. LLDB's own formatter however isn't following that behaviour which leads to situations where the formatted result is sometimes one second off. For example: ``` (lldb) p [NSDate dateWithTimeIntervalSince1970:0.1] (__NSTaggedDate *) $1 = [...] 1970-01-01 00:00:01 UTC (lldb) po [NSDate dateWithTimeIntervalSince1970:0.1] 1970-01-01 00:00:00 +0000 (lldb) p [NSDate dateWithTimeIntervalSince1970:0.6] (__NSTaggedDate *) $4 =[...] 1970-01-01 00:00:01 UTC (lldb) po [NSDate dateWithTimeIntervalSince1970:0.6] 1970-01-01 00:00:00 +0000 ``` This patch just always rounds down the seconds value we get from the NSDate object. Fixes rdar://65084800 Reviewers: mib, davide Reviewed By: mib Subscribers: JDevlieghere Differential Revision: https://reviews.llvm.org/D83221 --- lldb/source/Plugins/Language/ObjC/Cocoa.cpp | 2 +- .../data-formatter-objc/TestDataFormatterObjCNSDate.py | 9 +++++++++ .../functionalities/data-formatter/data-formatter-objc/main.m | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 8a44811..da910f48 100644 --- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -867,7 +867,7 @@ bool lldb_private::formatters::NSDateSummaryProvider( // is generally true and POSIXly happy, but might break if a library vendor // decides to get creative time_t epoch = GetOSXEpoch(); - epoch = epoch + (time_t)date_value; + epoch = epoch + static_cast(std::floor(date_value)); tm *tm_date = gmtime(&epoch); if (!tm_date) return false; diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py index 5cfaa89..61394c0 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py @@ -43,6 +43,15 @@ class ObjCDataFormatterNSDate(ObjCDataFormatterTestCase): self.expect('frame variable date4_abs', substrs=['1970']) self.expect('frame variable date5_abs', substrs=[now_year]) + # Check that LLDB always follow's NSDate's rounding behavior (which + # is always rounding down). + self.expect_expr("date_1970_minus_06", result_summary="1969-12-31 23:59:59 UTC") + self.expect_expr("date_1970_minus_05", result_summary="1969-12-31 23:59:59 UTC") + self.expect_expr("date_1970_minus_04", result_summary="1969-12-31 23:59:59 UTC") + self.expect_expr("date_1970_plus_06", result_summary="1970-01-01 00:00:00 UTC") + self.expect_expr("date_1970_plus_05", result_summary="1970-01-01 00:00:00 UTC") + self.expect_expr("date_1970_plus_04", result_summary="1970-01-01 00:00:00 UTC") + self.expect('frame variable cupertino home europe', substrs=['@"America/Los_Angeles"', '@"Europe/Rome"', diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m index df96a5e..a44a783 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m @@ -655,6 +655,14 @@ int main(int argc, const char *argv[]) { [NSDate dateWithTimeIntervalSinceReferenceDate: floor([[NSDate date] timeIntervalSinceReferenceDate])]; + NSDate *date_1970_minus_06 = [NSDate dateWithTimeIntervalSince1970:-0.6]; + NSDate *date_1970_minus_05 = [NSDate dateWithTimeIntervalSince1970:-0.5]; + NSDate *date_1970_minus_04 = [NSDate dateWithTimeIntervalSince1970:-0.4]; + + NSDate *date_1970_plus_06 = [NSDate dateWithTimeIntervalSince1970:0.6]; + NSDate *date_1970_plus_05 = [NSDate dateWithTimeIntervalSince1970:0.5]; + NSDate *date_1970_plus_04 = [NSDate dateWithTimeIntervalSince1970:0.4]; + CFAbsoluteTime date1_abs = CFDateGetAbsoluteTime(date1); CFAbsoluteTime date2_abs = CFDateGetAbsoluteTime(date2); CFAbsoluteTime date3_abs = CFDateGetAbsoluteTime(date3); -- 2.7.4