[libcxx-commits] [libcxx] c4a42f6 - [libc++] Fix the declarative generation of FTMs (#108843)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 17 11:27:41 PDT 2024


Author: Louis Dionne
Date: 2024-09-17T14:27:37-04:00
New Revision: c4a42f61151c585b80122108d961ebfd0e29544c

URL: https://github.com/llvm/llvm-project/commit/c4a42f61151c585b80122108d961ebfd0e29544c
DIFF: https://github.com/llvm/llvm-project/commit/c4a42f61151c585b80122108d961ebfd0e29544c.diff

LOG: [libc++] Fix the declarative generation of FTMs (#108843)

We were incorrectly computing whether a FTM has been implemented.
Instead of checking whether any version of the FTM is implemented for
the current Standard, we need to make sure that the correct version of
the FTM has been implemented.

As a drive-by fix, also correctly close the file that we load JSON from,
which was forgotten.

Added: 
    

Modified: 
    libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
    libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py
    libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py
    libcxx/test/libcxx/feature_test_macro/test_data.json
    libcxx/test/libcxx/feature_test_macro/version_header.sh.py
    libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py b/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
index 1dec1ae612ecb1..8c47448a800415 100644
--- a/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/ftm_metadata.sh.py
@@ -47,5 +47,10 @@ def test(output, expected):
             "test_suite_guard": None,
             "libcxx_guard": None,
         },
+        "__cpp_lib_missing_FTM_in_older_standard": {
+            "headers": [],
+            "test_suite_guard": None,
+            "libcxx_guard": None,
+        },
     },
 )

diff  --git a/libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py b/libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py
index 62a3c46b15db3c..942cd4b6087608 100644
--- a/libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/implemented_ftms.sh.py
@@ -50,5 +50,10 @@ def test(output, expected):
             "c++23": "202102L",
             "c++26": "202102L",
         },
+        "__cpp_lib_missing_FTM_in_older_standard": {
+            "c++17": None,
+            "c++20": None,
+            "c++26": None,
+        },
     },
 )

diff  --git a/libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py b/libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py
index 231e6072898752..95c9b9baaf2fa4 100644
--- a/libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/standard_ftms.sh.py
@@ -50,5 +50,11 @@ def test(output, expected):
             "c++23": "202106L",
             "c++26": "202306L",
         },
+        "__cpp_lib_missing_FTM_in_older_standard": {
+            "c++17": "2017L",
+            "c++20": "2020L",
+            "c++23": "2020L",
+            "c++26": "2026L",
+        },
     },
 )

diff  --git a/libcxx/test/libcxx/feature_test_macro/test_data.json b/libcxx/test/libcxx/feature_test_macro/test_data.json
index 18c8836fa5149f..f7ae74fb83286c 100644
--- a/libcxx/test/libcxx/feature_test_macro/test_data.json
+++ b/libcxx/test/libcxx/feature_test_macro/test_data.json
@@ -154,5 +154,35 @@
     "headers": [
       "variant"
     ]
+  },
+  {
+    "name": "__cpp_lib_missing_FTM_in_older_standard",
+    "values": {
+      "c++17": {
+        "2017": [
+          {
+            "title": "Some FTM missing a paper in an older Standard mode, which should result in the FTM never being defined.",
+            "implemented": false
+          }
+        ]
+      },
+      "c++20": {
+        "2020": [
+          {
+            "title": "",
+            "implemented": true
+          }
+        ]
+      },
+      "c++26": {
+        "2026": [
+          {
+            "title": "",
+            "implemented": true
+          }
+        ]
+      }
+    },
+    "headers": []
   }
 ]

diff  --git a/libcxx/test/libcxx/feature_test_macro/version_header.sh.py b/libcxx/test/libcxx/feature_test_macro/version_header.sh.py
index bbb863371f7639..634f43b83cafaa 100644
--- a/libcxx/test/libcxx/feature_test_macro/version_header.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/version_header.sh.py
@@ -43,6 +43,7 @@ def test(output, expected):
 #  define __cpp_lib_any 201606L
 #  define __cpp_lib_parallel_algorithm 201603L
 #  define __cpp_lib_variant 202102L
+// define __cpp_lib_missing_FTM_in_older_standard 2017L
 #endif // _LIBCPP_STD_VER >= 17
 
 #if _LIBCPP_STD_VER >= 20
@@ -50,8 +51,8 @@ def test(output, expected):
 #    define __cpp_lib_barrier 201907L
 #  endif
 // define __cpp_lib_format 202110L
-#  undef __cpp_lib_variant
-#  define __cpp_lib_variant 202106L
+// define __cpp_lib_variant 202106L
+// define __cpp_lib_missing_FTM_in_older_standard 2020L
 #endif // _LIBCPP_STD_VER >= 20
 
 #if _LIBCPP_STD_VER >= 23
@@ -64,8 +65,8 @@ def test(output, expected):
 #    define __cpp_lib_barrier 299900L
 #  endif
 // define __cpp_lib_format 202311L
-#  undef __cpp_lib_variant
-#  define __cpp_lib_variant 202306L
+// define __cpp_lib_variant 202306L
+// define __cpp_lib_missing_FTM_in_older_standard 2026L
 #endif // _LIBCPP_STD_VER >= 26
 
 #endif // _LIBCPP_VERSION

diff  --git a/libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py b/libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py
index db90206ae770f3..a2fc1c5682f63b 100644
--- a/libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py
+++ b/libcxx/test/libcxx/feature_test_macro/version_header_implementation.sh.py
@@ -9,106 +9,137 @@
 # RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
 
 import sys
+import unittest
 
-sys.path.append(sys.argv[1])
-from generate_feature_test_macro_components import FeatureTestMacros
-
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
 
-def test(output, expected):
-    assert output == expected, f"expected\n{expected}\n\noutput\n{output}"
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
 
+class Test(unittest.TestCase):
+    def setUp(self):
+        self.ftm = FeatureTestMacros(TEST_DATA)
+        self.maxDiff = None # This causes the 
diff  to be printed when the test fails
 
-ftm = FeatureTestMacros(sys.argv[2])
-test(
-    ftm.version_header_implementation,
-    {
-        "17": [
-            {
-                "__cpp_lib_any": {
-                    "value": "201606L",
-                    "implemented": True,
-                    "need_undef": False,
-                    "condition": None,
+    def test_implementation(self):
+        expected = {
+            "17": [
+                {
+                    "__cpp_lib_any": {
+                        "value": "201606L",
+                        "implemented": True,
+                        "need_undef": False,
+                        "condition": None,
+                    },
+                },
+                {
+                    "__cpp_lib_parallel_algorithm": {
+                        "value": "201603L",
+                        "implemented": True,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-            {
-                "__cpp_lib_parallel_algorithm": {
-                    "value": "201603L",
-                    "implemented": True,
-                    "need_undef": False,
-                    "condition": None,
+                {
+                    "__cpp_lib_variant": {
+                        "value": "202102L",
+                        "implemented": True,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-            {
-                "__cpp_lib_variant": {
-                    "value": "202102L",
-                    "implemented": True,
-                    "need_undef": False,
-                    "condition": None,
+                {
+                    "__cpp_lib_missing_FTM_in_older_standard": {
+                        "value": "2017L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-        ],
-        "20": [
-            {
-                "__cpp_lib_barrier": {
-                    "value": "201907L",
-                    "implemented": True,
-                    "need_undef": False,
-                    "condition": "!defined(_LIBCPP_HAS_NO_THREADS) && _LIBCPP_AVAILABILITY_HAS_SYNC",
+            ],
+            "20": [
+                {
+                    "__cpp_lib_barrier": {
+                        "value": "201907L",
+                        "implemented": True,
+                        "need_undef": False,
+                        "condition": "!defined(_LIBCPP_HAS_NO_THREADS) && _LIBCPP_AVAILABILITY_HAS_SYNC",
+                    },
                 },
-            },
-            {
-                "__cpp_lib_format": {
-                    "value": "202110L",
-                    "implemented": False,
-                    "need_undef": False,
-                    "condition": None,
+                {
+                    "__cpp_lib_format": {
+                        "value": "202110L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-            {
-                "__cpp_lib_variant": {
-                    "value": "202106L",
-                    "implemented": True,
-                    "need_undef": True,
-                    "condition": None,
+                {
+                    "__cpp_lib_variant": {
+                        "value": "202106L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-        ],
-        "23": [
-            {
-                "__cpp_lib_format": {
-                    "value": "202207L",
-                    "implemented": False,
-                    "need_undef": False,
-                    "condition": None,
+                {
+                    "__cpp_lib_missing_FTM_in_older_standard": {
+                        "value": "2020L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-        ],
-        "26": [
-            {
-                "__cpp_lib_barrier": {
-                    "value": "299900L",
-                    "implemented": True,
-                    "need_undef": True,
-                    "condition": "!defined(_LIBCPP_HAS_NO_THREADS) && _LIBCPP_AVAILABILITY_HAS_SYNC",
+            ],
+            "23": [
+                {
+                    "__cpp_lib_format": {
+                        "value": "202207L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-            {
-                "__cpp_lib_format": {
-                    "value": "202311L",
-                    "implemented": False,
-                    "need_undef": False,
-                    "condition": None,
+            ],
+            "26": [
+                {
+                    "__cpp_lib_barrier": {
+                        "value": "299900L",
+                        "implemented": True,
+                        "need_undef": True,
+                        "condition": "!defined(_LIBCPP_HAS_NO_THREADS) && _LIBCPP_AVAILABILITY_HAS_SYNC",
+                    },
                 },
-            },
-            {
-                "__cpp_lib_variant": {
-                    "value": "202306L",
-                    "implemented": True,
-                    "need_undef": True,
-                    "condition": None,
+                {
+                    "__cpp_lib_format": {
+                        "value": "202311L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
                 },
-            },
-        ],
-    },
-)
+                {
+                    "__cpp_lib_variant": {
+                        "value": "202306L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
+                },
+                {
+                    "__cpp_lib_missing_FTM_in_older_standard": {
+                        "value": "2026L",
+                        "implemented": False,
+                        "need_undef": False,
+                        "condition": None,
+                    },
+                },
+            ],
+        }
+
+        self.assertEqual(self.ftm.version_header_implementation, expected)
+
+if __name__ == '__main__':
+    unittest.main()

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index cb5ff770b1196e..3b8a52362ede68 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -2102,7 +2102,8 @@ class FeatureTestMacros:
 
     def __init__(self, filename: str):
         """Initializes the class with the JSON data in the file 'filename'."""
-        self.__data = json.load(open(filename))
+        with open(filename) as f:
+            self.__data = json.load(f)
 
     @functools.cached_property
     def std_dialects(self) -> List[str]:
@@ -2187,8 +2188,8 @@ def version_header_implementation(self) -> Dict[str, List[Dict[str, Any]]]:
             result[get_std_number(std)] = list()
 
         for ftm, values in self.standard_ftms.items():
-            need_undef = False
             last_value = None
+            last_entry = None
             for std, value in values.items():
                 # When a newer Standard does not change the value of the macro
                 # there is no need to redefine it with the same value.
@@ -2198,12 +2199,11 @@ def version_header_implementation(self) -> Dict[str, List[Dict[str, Any]]]:
 
                 entry = dict()
                 entry["value"] = value
-                entry["implemented"] = self.implemented_ftms[ftm][std] != None
-                entry["need_undef"] = need_undef
+                entry["implemented"] = self.implemented_ftms[ftm][std] == self.standard_ftms[ftm][std]
+                entry["need_undef"] = last_entry is not None and last_entry["implemented"] and entry["implemented"]
                 entry["condition"] = self.ftm_metadata[ftm]["libcxx_guard"]
 
-                need_undef = entry["implemented"]
-
+                last_entry = entry
                 result[get_std_number(std)].append(dict({ftm: entry}))
 
         return result


        


More information about the libcxx-commits mailing list