[libcxx-commits] [libcxx] [libcxx] fix mi_mode_test failure with libc++-21 (PR #153969)

Sv. Lockal via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 16 10:59:40 PDT 2025


https://github.com/AngryLoki created https://github.com/llvm/llvm-project/pull/153969

This test attempts to compare JSON-serialized objects produced by the GDB pretty printer. While it happened to work in libstdc++ and libc++-20, it fails in libc++-21 because `std::unordered_map` does not guarantee ordering.

The test now compares sorted lists for `std::unordered_map` and adds subtests for `std::set`/`std::unordered_set`.


>From b4097e34ed97eb9d3c0c6ad37ea8f99c89f129b1 Mon Sep 17 00:00:00 2001
From: "Sv. Lockal" <lockalsash at gmail.com>
Date: Sat, 16 Aug 2025 17:58:35 +0000
Subject: [PATCH] [libcxx] fix mi_mode_test failure with libc++-21

This test attempts to compare JSON-serialized objects produced by the GDB pretty printer. While it happened to work in libstdc++ and libc++-20, it fails in libc++-21 because `std::unordered_map` does not guarantee ordering.

The test now compares sorted lists for `std::unordered_map` and adds subtests for `std::set`/`std::unordered_set`.
---
 .../libcxx/gdb/gdb_pretty_printer_test.py     | 13 +++++++---
 .../libcxx/gdb/gdb_pretty_printer_test.sh.cpp | 26 ++++++++++++-------
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
index da09092b690c4..30d669e5b00ca 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.py
@@ -45,7 +45,8 @@ def invoke(self, arg, from_tty):
 
             # Stack frame is:
             # 0. StopForDebugger
-            # 1. CompareListChildrenToChars, ComparePrettyPrintToChars or ComparePrettyPrintToRegex
+            # 1. CompareListChildrenToChars, CompareListChildrenSortedToChars,
+            #    ComparePrettyPrintToChars or ComparePrettyPrintToRegex
             # 2. TestCase
             compare_frame = gdb.newest_frame().older()
             testcase_frame = compare_frame.older()
@@ -57,7 +58,9 @@ def invoke(self, arg, from_tty):
             frame_name = compare_frame.name()
             if frame_name.startswith("CompareListChildren"):
                 if has_execute_mi:
-                    value = self._get_children(compare_frame)
+                    value = self._get_children(
+                        compare_frame, with_sorting="Sorted" in frame_name
+                    )
                 else:
                     print("SKIPPED: " + test_loc_str)
                     return
@@ -91,7 +94,7 @@ def invoke(self, arg, from_tty):
             print(str(e))
             test_failures += 1
 
-    def _get_children(self, compare_frame):
+    def _get_children(self, compare_frame, *, with_sorting=False):
         compare_frame.select()
         gdb.execute_mi("-var-create", "value", "*", "value")
         r = gdb.execute_mi("-var-list-children", "--simple-values", "value")
@@ -105,8 +108,12 @@ def _get_children(self, compare_frame):
                 }
                 for i in range(len(children) // 2)
             ]
+            if with_sorting:
+                r.sort(key=lambda item: item["key"])
         else:
             r = [json.loads(el["value"]) for el in children]
+            if with_sorting:
+                r.sort()
         return json.dumps(r, sort_keys=True)
 
     def _get_value(self, compare_frame, testcase_frame):
diff --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
index f5a878582666b..fe2fcec0c0a9e 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -136,6 +136,12 @@ void CompareListChildrenToChars(TypeToPrint value, const char* expectation) {
   StopForDebugger(&value, &expectation);
 }
 
+template <typename TypeToPrint>
+void CompareListChildrenSortedToChars(TypeToPrint value, const char* expectation) {
+  MarkAsLive(value);
+  StopForDebugger(&value, &expectation);
+}
+
 namespace example {
   struct example_struct {
     int a = 0;
@@ -672,19 +678,19 @@ void streampos_test() {
 }
 
 void mi_mode_test() {
-  std::map<int, std::string> one_two_three_map;
-  one_two_three_map.insert({1, "one"});
-  one_two_three_map.insert({2, "two"});
-  one_two_three_map.insert({3, "three"});
+  std::set<std::string> one_two_three_set{"3", "2", "1"};
+  CompareListChildrenToChars(one_two_three_set, R"(["1", "2", "3"])");
+
+  std::unordered_set<std::string> one_two_three_uset{"3", "2", "1"};
+  CompareListChildrenSortedToChars(one_two_three_uset, R"(["1", "2", "3"])");
+
+  std::map<int, std::string> one_two_three_map{{3, "three"}, {2, "two"}, {1, "one"}};
   CompareListChildrenToChars(
       one_two_three_map, R"([{"key": 1, "value": "one"}, {"key": 2, "value": "two"}, {"key": 3, "value": "three"}])");
 
-  std::unordered_map<int, std::string> one_two_three_umap;
-  one_two_three_umap.insert({3, "three"});
-  one_two_three_umap.insert({2, "two"});
-  one_two_three_umap.insert({1, "one"});
-  CompareListChildrenToChars(
-      one_two_three_umap, R"([{"key": 3, "value": "three"}, {"key": 2, "value": "two"}, {"key": 1, "value": "one"}])");
+  std::unordered_map<int, std::string> one_two_three_umap{{3, "three"}, {2, "two"}, {1, "one"}};
+  CompareListChildrenSortedToChars(
+      one_two_three_umap, R"([{"key": 1, "value": "one"}, {"key": 2, "value": "two"}, {"key": 3, "value": "three"}])");
 
   std::deque<int> one_two_three_deque{1, 2, 3};
   CompareListChildrenToChars(one_two_three_deque, "[1, 2, 3]");



More information about the libcxx-commits mailing list