Skip to content

Commit 8cb10d6

Browse files
authored
Add tests for checking integral return types (#26603)
This adds test cases for mixing of `int` and `uint` types in conditional branches for both dyno and prod. A discrepancy in return types between prod and dyno was noticed in Cray/chapel-private#6829 and determined to be a bug in prod, captured in #26991. These tests capture the current state of prod and dyno, placing the prod tests in a future. TESTING: - [x] paratest `[Summary: #Successes = 17797 | #Failures = 0 | #Futures = 906]` [reviewed by @benharsh - thanks!]
2 parents a67b96c + 86b9d13 commit 8cb10d6

10 files changed

+2238
-0
lines changed

frontend/test/resolution/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ comp_unit_test(testGetSymbolsAvailableInScope)
5151
comp_unit_test(testHeapBuffer)
5252
comp_unit_test(testIf)
5353
comp_unit_test(testInitSemantics)
54+
comp_unit_test(testIntegralReturnType)
5455
comp_unit_test(testInteractive)
5556
comp_unit_test(testInterfaces)
5657
comp_unit_test(testIterators)

frontend/test/resolution/testIntegralReturnType.cpp

+521
Large diffs are not rendered by default.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
integralTests.chpl
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
integralTests.chpl

test/statements/conditionals/integralReturnTypesInConditional.bad

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require "integralTests.chpl";
2+
use integralTests;

test/statements/conditionals/integralReturnTypesInConditional.expected

+1,536
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The return type of an expression or statement should not be sensitive to the order
2+
of the branches in a conditional statement.
3+
#26991

test/statements/conditionals/integralReturnTypesInConditional.good

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env python3
2+
3+
integral_types = [
4+
"int(8)", "int(16)", "int(32)", "int(64)",
5+
"uint(8)", "uint(16)", "uint(32)", "uint(64)"
6+
]
7+
8+
boolean_strs = ["true", "false"]
9+
10+
output_file = "integralTests.chpl"
11+
# open the input file to read the expected results of each test case
12+
input_file = "integralReturnTypesInConditional.expected"
13+
14+
# read the input file into a map where the key is made up of the test name, bool_str, type1, and type2.
15+
# The value is the expected result
16+
test_map = {}
17+
with open(input_file, "r") as f:
18+
for line in f:
19+
parts = line.strip().split()
20+
if len(parts) == 7:
21+
test_name, _, bool_str, type1, type2, _, expected_result = parts
22+
key = (test_name, bool_str, type1, type2)
23+
test_map[key] = expected_result
24+
else:
25+
raise ValueError(f"Unexpected line format: {line.strip()}")
26+
27+
28+
with open(output_file, "w") as f:
29+
for bool_str in boolean_strs:
30+
for type1 in integral_types:
31+
for type2 in integral_types:
32+
f.write("{\n")
33+
f.write(f" proc testProcCastZero(arg: bool) {{\n")
34+
f.write(f" if arg then return 0:{type1}; else return 0:{type2};\n")
35+
f.write(" }\n")
36+
f.write(f" var x = testProcCastZero({bool_str});\n")
37+
# Check if the test case exists in the map
38+
if (f"testProcCastZero:", bool_str, type1, type2) in test_map:
39+
expected_result = test_map[(f"testProcCastZero:", bool_str, type1, type2)]
40+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
41+
# f.write(f" writeln(\"testProcCastZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
42+
f.write("}\n\n")
43+
44+
f.write("{\n")
45+
f.write(f" proc testProcZero(arg: bool) {{\n")
46+
f.write(f" var i: {type1} = 0;\n")
47+
f.write(f" var u: {type2} = 0;\n")
48+
f.write(f" if arg then return i; else return u;\n")
49+
f.write(" }\n")
50+
f.write(f" var x = testProcZero({bool_str});\n")
51+
# Check if the test case exists in the map
52+
if (f"testProcZero:", bool_str, type1, type2) in test_map:
53+
expected_result = test_map[(f"testProcZero:", bool_str, type1, type2)]
54+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
55+
# f.write(f" writeln(\"testProcZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
56+
f.write("}\n\n")
57+
58+
f.write("{\n")
59+
f.write(f" proc testProcCastMax(arg: bool) {{\n")
60+
f.write(f" if arg then return max({type1}):{type1}; else return max({type2}):{type2};\n")
61+
f.write(" }\n")
62+
f.write(f" var x = testProcCastMax({bool_str});\n")
63+
# Check if the test case exists in the map
64+
if (f"testProcCastMax:", bool_str, type1, type2) in test_map:
65+
expected_result = test_map[(f"testProcCastMax:", bool_str, type1, type2)]
66+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
67+
# f.write(f" writeln(\"testProcCastMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
68+
f.write("}\n\n")
69+
70+
f.write("{\n")
71+
f.write(f" proc testProcMax(arg: bool) {{\n")
72+
f.write(f" var i: {type1} = max({type1});\n")
73+
f.write(f" var u: {type2} = max({type2});\n")
74+
f.write(f" if arg then return i; else return u;\n")
75+
f.write(" }\n")
76+
f.write(f" var x = testProcMax({bool_str});\n")
77+
# Check if the test case exists in the map
78+
if (f"testProcMax:", bool_str, type1, type2) in test_map:
79+
expected_result = test_map[(f"testProcMax:", bool_str, type1, type2)]
80+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
81+
# f.write(f" writeln(\"testProcMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
82+
f.write("}\n\n")
83+
84+
f.write("{\n")
85+
f.write(f" proc testParamProcCastZero(param arg: bool) param {{\n")
86+
f.write(f" if arg then return 0:{type1}; else return 0:{type2};\n")
87+
f.write(" }\n")
88+
f.write(f" param x = testParamProcCastZero({bool_str});\n")
89+
# Check if the test case exists in the map
90+
if (f"testParamProcCastZero:", bool_str, type1, type2) in test_map:
91+
expected_result = test_map[(f"testParamProcCastZero:", bool_str, type1, type2)]
92+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
93+
# f.write(f" writeln(\"testParamProcCastZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
94+
f.write("}\n\n")
95+
96+
f.write("{\n")
97+
f.write(f" proc testParamProcZero(param arg: bool) param {{\n")
98+
f.write(f" param i: {type1} = 0;\n")
99+
f.write(f" param u: {type2} = 0;\n")
100+
f.write(f" if arg then return i; else return u;\n")
101+
f.write(" }\n")
102+
f.write(f" param x = testParamProcZero({bool_str});\n")
103+
# Check if the test case exists in the map
104+
if (f"testParamProcZero:", bool_str, type1, type2) in test_map:
105+
expected_result = test_map[(f"testParamProcZero:", bool_str, type1, type2)]
106+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
107+
# f.write(f" writeln(\"testParamProcZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
108+
f.write("}\n\n")
109+
110+
f.write("{\n")
111+
f.write(f" proc testParamProcCastMax(param arg: bool) param {{\n")
112+
f.write(f" if arg then return max({type1}):{type1}; else return max({type2}):{type2};\n")
113+
f.write(" }\n")
114+
f.write(f" param x = testParamProcCastMax({bool_str});\n")
115+
# Check if the test case exists in the map
116+
if (f"testParamProcCastMax:", bool_str, type1, type2) in test_map:
117+
expected_result = test_map[(f"testParamProcCastMax:", bool_str, type1, type2)]
118+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
119+
# f.write(f" writeln(\"testParamProcCastMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
120+
f.write("}\n\n")
121+
122+
f.write("{\n")
123+
f.write(f" proc testParamProcMax(param arg: bool) param {{\n")
124+
f.write(f" param i: {type1} = max({type1});\n")
125+
f.write(f" param u: {type2} = max({type2});\n")
126+
f.write(f" if arg then return i; else return u;\n")
127+
f.write(" }\n")
128+
f.write(f" param x = testParamProcMax({bool_str});\n")
129+
# Check if the test case exists in the map
130+
if (f"testParamProcMax:", bool_str, type1, type2) in test_map:
131+
expected_result = test_map[(f"testParamProcMax:", bool_str, type1, type2)]
132+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
133+
# f.write(f" writeln(\"testParamProcMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
134+
f.write("}\n\n")
135+
136+
f.write("{\n")
137+
f.write(f" var b: bool = {bool_str};\n")
138+
f.write(f" var x = if b then 0:{type1} else 0:{type2};\n")
139+
# Check if the test case exists in the map
140+
if (f"testExpressionZero:", bool_str, type1, type2) in test_map:
141+
expected_result = test_map[(f"testExpressionZero:", bool_str, type1, type2)]
142+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
143+
# f.write(f" writeln(\"testExpressionZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
144+
f.write("}\n\n")
145+
146+
f.write("{\n")
147+
f.write(f" var b: bool = {bool_str};\n")
148+
f.write(f" var x = if b then max({type1}):{type1} else max({type2}):{type2};\n")
149+
# Check if the test case exists in the map
150+
if (f"testExpressionMax:", bool_str, type1, type2) in test_map:
151+
expected_result = test_map[(f"testExpressionMax:", bool_str, type1, type2)]
152+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
153+
# f.write(f" writeln(\"testExpressionMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
154+
f.write("}\n\n")
155+
156+
f.write("{\n")
157+
f.write(f" param x = if {bool_str} then 0:{type1} else 0:{type2};\n")
158+
# Check if the test case exists in the map
159+
if (f"testParamExpressionZero:", bool_str, type1, type2) in test_map:
160+
expected_result = test_map[(f"testParamExpressionZero:", bool_str, type1, type2)]
161+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
162+
# f.write(f" writeln(\"testParamExpressionZero: when {bool_str} {type1} {type2} then \", x.type:string);\n")
163+
f.write("}\n\n")
164+
165+
f.write("{\n")
166+
f.write(f" param x = if {bool_str} then max({type1}):{type1} else max({type2}):{type2};\n")
167+
# Check if the test case exists in the map
168+
if (f"testParamExpressionMax:", bool_str, type1, type2) in test_map:
169+
expected_result = test_map[(f"testParamExpressionMax:", bool_str, type1, type2)]
170+
f.write(f" assert(x.type:string == \"{expected_result}\");\n")
171+
172+
# f.write(f" writeln(\"testParamExpressionMax: when {bool_str} {type1} {type2} then \", x.type:string);\n")
173+
f.write("}\n\n")

0 commit comments

Comments
 (0)