Skip to content

Commit 07e77b6

Browse files
authored
Merge pull request #75 from FStarLang/_taramana_shift
Require shift RHS to be uint32_t, allow any unsigned int LHS
2 parents 157688c + 48e15a1 commit 07e77b6

3 files changed

Lines changed: 39 additions & 6 deletions

File tree

src/pass/check.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,21 @@ impl<'a> Checker<'a> {
278278
| BinOp::Sub
279279
| BinOp::BitAnd
280280
| BinOp::BitOr
281-
| BinOp::BitXor
282-
| BinOp::Shl
283-
| BinOp::Shr => check_eq(self),
281+
| BinOp::BitXor => check_eq(self),
282+
BinOp::Shl | BinOp::Shr => {
283+
let u32_ty: MaybeRc<Type> = TypeT::Int {
284+
signed: false,
285+
width: 32,
286+
}
287+
.with_loc(rhs.loc.clone())
288+
.into();
289+
if !env.vtype_eq(rhs_ty.clone().into(), u32_ty) {
290+
self.report(
291+
format!("shift amount must be uint32_t, not {}", rhs_ty),
292+
&rval.loc,
293+
)
294+
}
295+
}
284296
}
285297
}
286298
}

src/pass/elab.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,7 @@ impl<'a> Elaborator<'a> {
247247
| BinOp::Implies
248248
| BinOp::BitAnd
249249
| BinOp::BitOr
250-
| BinOp::BitXor
251-
| BinOp::Shl
252-
| BinOp::Shr => {
250+
| BinOp::BitXor => {
253251
if let Some(meet_type) = env.meet_type(lhs_ty.clone(), rhs_ty.clone()) {
254252
if !env.vtype_eq(lhs_ty, meet_type.clone()) {
255253
cast_to(lhs, meet_type.clone().to_rc())
@@ -267,6 +265,17 @@ impl<'a> Elaborator<'a> {
267265
);
268266
}
269267
}
268+
BinOp::Shl | BinOp::Shr => {
269+
let u32_ty: MaybeRc<Type> = TypeT::Int {
270+
signed: false,
271+
width: 32,
272+
}
273+
.with_loc(rhs.loc.clone())
274+
.into();
275+
if !env.vtype_eq(rhs_ty, u32_ty.clone()) {
276+
cast_to(rhs, u32_ty.to_rc())
277+
}
278+
}
270279
}
271280
}
272281
ExprT::BoolLit(_) => {}

test/bitops.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,15 @@ uint32_t test_shr(uint32_t a, uint32_t b)
3636
{
3737
return a >> b;
3838
}
39+
40+
uint64_t test_shl64(uint64_t a, uint32_t b)
41+
_requires(b < 64u)
42+
{
43+
return a << b;
44+
}
45+
46+
uint64_t test_shr64(uint64_t a, uint32_t b)
47+
_requires(b < 64u)
48+
{
49+
return a >> b;
50+
}

0 commit comments

Comments
 (0)