Skip to content

Commit 5463518

Browse files
authored
cgen: ensure that << and >> has higher precedence in the generated C code, than arithmetic operations (diff between C and V precedences) (#18814)
1 parent 17b5762 commit 5463518

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

vlib/v/gen/c/infix.v

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,17 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
3535
g.infix_expr_arithmetic_op(node)
3636
}
3737
.left_shift {
38+
// `a << b` can mean many things in V ...
39+
// TODO: disambiguate everything in the checker; cgen should not decide all this.
40+
// Instead it should be as simple, as the branch for .right_shift is.
41+
// `array << val` should have its own separate operation internally.
3842
g.infix_expr_left_shift_op(node)
3943
}
44+
.right_shift {
45+
g.write('(')
46+
g.gen_plain_infix_expr(node)
47+
g.write(')')
48+
}
4049
.and, .logical_or {
4150
g.infix_expr_and_or_op(node)
4251
}
@@ -846,7 +855,9 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
846855
}
847856
}
848857
} else {
858+
g.write('(')
849859
g.gen_plain_infix_expr(node)
860+
g.write(')')
850861
}
851862
}
852863

vlib/v/tests/shift_test.v

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
type MyInt = int
22

3+
fn test_shift_left_precedence() {
4+
x := u32(20)
5+
base := u32(1)
6+
shift := u32(3)
7+
assert x + base << shift == (x + (base << shift)), '<< should have higher precedence than +'
8+
assert x - base << shift == (x - (base << shift)), '<< should have higher precedence than -'
9+
}
10+
11+
fn test_shift_right_precedence() {
12+
x := u32(20)
13+
base := u32(100)
14+
shift := u32(2)
15+
assert x + base >> shift == (x + (base >> shift)), '>> should have higher precedence than +'
16+
assert x - base >> shift == (x - (base >> shift)), '>> should have higher precedence than -'
17+
}
18+
319
fn test_shift_operators() {
420
// check that shift works with all integer types
521
// as the right-hand side operand

0 commit comments

Comments
 (0)