Skip to content

Commit 7c00482

Browse files
committed
Support float in conditions.
1 parent 4713cc0 commit 7c00482

4 files changed

Lines changed: 159 additions & 5 deletions

File tree

co2_hir/src/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ pub(crate) fn is_condition_ty(ty: Ty) -> bool {
378378
RigidTy::Bool
379379
| RigidTy::Int(_)
380380
| RigidTy::Uint(_)
381+
| RigidTy::Float(_)
381382
| RigidTy::RawPtr(_, _)
382383
| RigidTy::FnPtr(_)
383384
| RigidTy::FnDef(_, _)

co2_mir/src/operand.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,32 @@ impl Builder<'_, '_> {
15801580
});
15811581
return MirOperand::Copy(place(bool_local));
15821582
}
1583+
if dst_is_bool && src_is_float {
1584+
let TyKind::RigidTy(RigidTy::Float(float_ty)) = src_ty.kind() else {
1585+
unreachable!("src_is_float implies float type");
1586+
};
1587+
let zero = MirOperand::Constant(ConstOperand {
1588+
span,
1589+
user_ty: None,
1590+
const_: MirConst::try_from_float(0.0, float_ty).expect("failed to build float zero"),
1591+
});
1592+
let bool_local = self.new_temp(Ty::bool_ty(), Mutability::Mut, span);
1593+
self.stmts.push(MirStatement {
1594+
kind: MirStatementKind::Assign(
1595+
place(bool_local),
1596+
Rvalue::BinaryOp(
1597+
rustc_public_generative::rustc_public::mir::BinOp::Ne,
1598+
inner_op,
1599+
zero,
1600+
),
1601+
),
1602+
source_info: SourceInfo {
1603+
span,
1604+
scope: self.current_scope(),
1605+
},
1606+
});
1607+
return MirOperand::Copy(place(bool_local));
1608+
}
15831609
if src_is_int && dst_is_int {
15841610
let tmp = self.new_temp(dst_ty, Mutability::Mut, span);
15851611
self.stmts.push(MirStatement {

rustc_public_generative/src/internal.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,11 +2207,9 @@ impl<S: CrateGeneratorState> InterfaceCallbacks<S> {
22072207
let sigs = ItemSignatureInfo::from_hir_structure(&hir_structure);
22082208
{
22092209
let mut guard = gate.state.try_lock().unwrap();
2210-
guard.defined_crate.advance_to_stage2(
2211-
sigs.clone(),
2212-
state,
2213-
context.clone(),
2214-
);
2210+
guard
2211+
.defined_crate
2212+
.advance_to_stage2(sigs.clone(), state, context.clone());
22152213
}
22162214
if should_patch_cached_resolutions(tcx) {
22172215
augment_cached_generated_resolutions(tcx);

tests/c/float/condition.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//@ mode: c
2+
//@ run-status: 0
3+
4+
#include <assert.h>
5+
#include <math.h>
6+
#include <float.h>
7+
8+
int main(void)
9+
{
10+
/* Basic truth values */
11+
assert((0.0 ? 0 : 1) == 1);
12+
assert((-0.0 ? 0 : 1) == 1);
13+
assert((1.0 ? 1 : 0) == 1);
14+
assert((-1.0 ? 1 : 0) == 1);
15+
16+
/* Smallest values */
17+
assert((DBL_MIN ? 1 : 0) == 1);
18+
19+
#if __STDC_VERSION__ >= 201112L
20+
assert((DBL_TRUE_MIN ? 1 : 0) == 1);
21+
#endif
22+
23+
/* Infinity and NaN */
24+
assert((INFINITY ? 1 : 0) == 1);
25+
assert((-INFINITY ? 1 : 0) == 1);
26+
assert((NAN ? 1 : 0) == 1);
27+
28+
/* if */
29+
{
30+
int x = 0;
31+
if (3.14)
32+
x = 1;
33+
assert(x == 1);
34+
35+
x = 0;
36+
if (0.0)
37+
x = 1;
38+
else
39+
x = 2;
40+
assert(x == 2);
41+
}
42+
43+
/* while */
44+
{
45+
int n = 0;
46+
while (2.0) {
47+
++n;
48+
break;
49+
}
50+
assert(n == 1);
51+
52+
n = 0;
53+
while (0.0)
54+
++n;
55+
assert(n == 0);
56+
}
57+
58+
/* do-while */
59+
{
60+
int n = 0;
61+
do {
62+
++n;
63+
} while (0.0);
64+
assert(n == 1);
65+
66+
n = 0;
67+
do {
68+
++n;
69+
} while (2.0 && n < 3);
70+
assert(n == 3);
71+
}
72+
73+
/* for */
74+
{
75+
int n = 0;
76+
for (; 1.0; ) {
77+
++n;
78+
break;
79+
}
80+
assert(n == 1);
81+
82+
n = 0;
83+
for (; 0.0; )
84+
++n;
85+
assert(n == 0);
86+
}
87+
88+
/* switch using ?: whose condition is floating-point */
89+
{
90+
switch (0.5 ? 10 : 20) {
91+
case 10:
92+
break;
93+
default:
94+
assert(0);
95+
}
96+
97+
switch (0.0 ? 10 : 20) {
98+
case 20:
99+
break;
100+
default:
101+
assert(0);
102+
}
103+
104+
switch (NAN ? 1 : 2) {
105+
case 1:
106+
break;
107+
default:
108+
assert(0);
109+
}
110+
}
111+
112+
/* Nested conditional operators */
113+
assert((0.0 ? 1 : 2.0 ? 3 : 4) == 3);
114+
assert((0.0 ? 1 : 0.0 ? 3 : 4) == 4);
115+
assert((NAN ? 5 : 6) == 5);
116+
117+
/* Volatile values (prevent over-optimization) */
118+
{
119+
volatile double z = 0.0;
120+
volatile double o = 1.0;
121+
122+
assert((o ? 1 : 0) == 1);
123+
assert((z ? 1 : 0) == 0);
124+
assert(((o / z) ? 1 : 0) == 1); /* +inf */
125+
assert(((z / z) ? 1 : 0) == 1); /* NaN */
126+
}
127+
128+
return 0;
129+
}

0 commit comments

Comments
 (0)