Skip to content

Commit 4e1f8c3

Browse files
committed
[libc++] Adds additional FTM imput validation.
This ensure the input is properly sorted; when not gives a nice diagnostic.
1 parent d2361e4 commit 4e1f8c3

File tree

2 files changed

+191
-1
lines changed

2 files changed

+191
-1
lines changed

libcxx/test/libcxx/feature_test_macro/invalid.sh.py

Lines changed: 168 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import json
1313

1414
sys.path.append(sys.argv[1])
15-
from generate_feature_test_macro_components import FeatureTestMacros
15+
from generate_feature_test_macro_components import FeatureTestMacros, DataNotSorted
1616

1717

1818
def test(output, expected):
@@ -106,3 +106,170 @@ def test_error(data, type, message):
106106
KeyError,
107107
"'implemented'",
108108
)
109+
110+
test_error(
111+
[
112+
{
113+
"name": "abc",
114+
"values": {
115+
"c++17": {
116+
"197001": [
117+
{
118+
"implemented": False,
119+
},
120+
],
121+
},
122+
},
123+
"headers": [],
124+
},
125+
{
126+
"name": "ghi",
127+
"values": {
128+
"c++17": {
129+
"197001": [
130+
{
131+
"implemented": False,
132+
},
133+
],
134+
},
135+
},
136+
"headers": [],
137+
},
138+
{ # This entry is in the wrong alphabetic order
139+
"name": "def",
140+
"values": {
141+
"c++17": {
142+
"197001": [
143+
{
144+
"implemented": False,
145+
},
146+
],
147+
},
148+
},
149+
"headers": [],
150+
},
151+
{
152+
"name": "jkl",
153+
"values": {
154+
"c++17": {
155+
"197001": [
156+
{
157+
"implemented": False,
158+
},
159+
],
160+
},
161+
},
162+
"headers": [],
163+
},
164+
],
165+
DataNotSorted,
166+
"""\
167+
The ftm names are not sorted.
168+
--- input data
169+
+++ sorted data
170+
@@ -1,4 +1,4 @@
171+
abc
172+
+def
173+
ghi
174+
-def
175+
jkl
176+
""",
177+
)
178+
179+
test_error(
180+
[
181+
{
182+
"name": "abc",
183+
"values": {
184+
"c++14": {
185+
"197001": [
186+
{
187+
"implemented": False,
188+
},
189+
],
190+
},
191+
"c++23": {
192+
"197001": [
193+
{
194+
"implemented": False,
195+
},
196+
],
197+
},
198+
# This entry is in the wrong alphabetic order
199+
# Note we don't use C++98, but C++03 instead so alphabetic order
200+
# works this century.
201+
"c++20": {
202+
"197001": [
203+
{
204+
"implemented": False,
205+
},
206+
],
207+
},
208+
},
209+
"headers": [],
210+
},
211+
],
212+
DataNotSorted,
213+
"""\
214+
The C++ standard version numbers of ftm 'abc' are not sorted.
215+
--- input data
216+
+++ sorted data
217+
@@ -1,3 +1,3 @@
218+
c++14
219+
+c++20
220+
c++23
221+
-c++20
222+
""",
223+
)
224+
225+
test_error(
226+
[
227+
{
228+
"name": "abc",
229+
"values": {
230+
"c++14": {
231+
"197001": [
232+
{
233+
"implemented": False,
234+
},
235+
],
236+
"197002": [
237+
{
238+
"implemented": False,
239+
},
240+
],
241+
"197004": [
242+
{
243+
"implemented": False,
244+
},
245+
],
246+
# This entry is in the wrong alphabetic order
247+
"197003": [
248+
{
249+
"implemented": False,
250+
},
251+
],
252+
"197005": [
253+
{
254+
"implemented": False,
255+
},
256+
],
257+
},
258+
},
259+
"headers": [],
260+
},
261+
],
262+
DataNotSorted,
263+
"""\
264+
The value of the fmt 'abc' in c++14 are not sorted.
265+
--- input data
266+
+++ sorted data
267+
@@ -1,5 +1,5 @@
268+
197001
269+
197002
270+
+197003
271+
197004
272+
-197003
273+
197005
274+
""",
275+
)

libcxx/utils/generate_feature_test_macro_components.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
from builtins import range
55
from dataclasses import dataclass
6+
from difflib import unified_diff
67
from functools import reduce
78
from typing import (
89
Any,
@@ -2021,6 +2022,25 @@ class FtmHeaderTest:
20212022
implemented: bool = None
20222023
condition: str = None
20232024

2025+
class DataNotSorted(Exception):
2026+
pass
2027+
2028+
def validate_sorted(name:str, data: List[str]) -> None:
2029+
sorted_data = sorted(data)
2030+
if data != sorted_data:
2031+
raise DataNotSorted(
2032+
f"The {name} are not sorted.\n"
2033+
+ "\n".join(
2034+
unified_diff(
2035+
data,
2036+
sorted_data,
2037+
"input data",
2038+
"sorted data",
2039+
lineterm="",
2040+
)
2041+
) + "\n"
2042+
)
2043+
20242044
def get_ftms(
20252045
data, std_dialects: List[Std], use_implemented_status: bool
20262046
) -> Dict[Ftm, Dict[Std, Optional[Value]]]:
@@ -2030,6 +2050,7 @@ def get_ftms(
20302050
last = None
20312051
entry = dict()
20322052
implemented = True
2053+
validate_sorted(f"C++ standard version numbers of ftm '{feature['name']}'", list(feature["values"].keys()))
20332054
for std in std_dialects:
20342055
if std not in feature["values"].keys():
20352056
if last == None:
@@ -2040,6 +2061,7 @@ def get_ftms(
20402061
if implemented:
20412062
values = feature["values"][std]
20422063
assert len(values) > 0, f"{feature['name']}[{std}] has no entries"
2064+
validate_sorted(f"value of the fmt '{feature['name']}' in {std}", list(values.keys()))
20432065
for value in values:
20442066
papers = list(values[value])
20452067
assert (
@@ -2058,6 +2080,7 @@ def get_ftms(
20582080
entry[std] = last
20592081
result[feature["name"]] = entry
20602082

2083+
validate_sorted("ftm names", list(result))
20612084
return result
20622085

20632086

0 commit comments

Comments
 (0)