@@ -1523,8 +1523,9 @@ static inline int32_t int32_bsr(int32_t n, unsigned int rshift)
1523
1523
static inline bool int32_bsl_overflow (int32_t n , unsigned int lshift , int32_t * out )
1524
1524
{
1525
1525
//
1526
- if ((n != 0 ) && (lshift > 64 )) {
1527
- return true;
1526
+ if ((n != 0 ) && (lshift > 32 )) {
1527
+ * out = 0 ;
1528
+ return (n != 0 );
1528
1529
}
1529
1530
//
1530
1531
@@ -1533,6 +1534,14 @@ static inline bool int32_bsl_overflow(int32_t n, unsigned int lshift, int32_t *o
1533
1534
int32_t check = int32_bsr (res , lshift );
1534
1535
return check != n ;
1535
1536
}
1537
+
1538
+ static inline int32_t int32_bsr_safe (int32_t n , unsigned int rshift )
1539
+ {
1540
+ if (rshift > 32 ) {
1541
+ return n < 0 ? -1 : 0 ;
1542
+ }
1543
+ return int32_bsr (n , rshift );
1544
+ }
1536
1545
#endif
1537
1546
1538
1547
static inline int64_t int64_bsr (int64_t n , unsigned int rshift )
@@ -1543,8 +1552,9 @@ static inline int64_t int64_bsr(int64_t n, unsigned int rshift)
1543
1552
static inline bool int64_bsl_overflow (int64_t n , unsigned int lshift , int64_t * out )
1544
1553
{
1545
1554
//
1546
- if ((n != 0 ) && (lshift > 64 )) {
1547
- return true;
1555
+ if (lshift > 64 ) {
1556
+ * out = 0 ;
1557
+ return (n != 0 );
1548
1558
}
1549
1559
//
1550
1560
@@ -1554,6 +1564,14 @@ static inline bool int64_bsl_overflow(int64_t n, unsigned int lshift, int64_t *o
1554
1564
return check != n ;
1555
1565
}
1556
1566
1567
+ static inline int64_t int64_bsr_safe (int64_t n , unsigned int rshift )
1568
+ {
1569
+ if (rshift > 64 ) {
1570
+ return n < 0 ? -1 : 0 ;
1571
+ }
1572
+ return int64_bsr (n , rshift );
1573
+ }
1574
+
1557
1575
term bif_erlang_bsl_2 (Context * ctx , uint32_t fail_label , int live , term arg1 , term arg2 )
1558
1576
{
1559
1577
if (LIKELY (term_is_any_integer (arg1 ) && term_is_any_integer (arg2 ))) {
@@ -1610,7 +1628,7 @@ term bif_erlang_bsr_2(Context *ctx, uint32_t fail_label, int live, term arg1, te
1610
1628
1611
1629
if (arg1_size <= BOXED_TERMS_REQUIRED_FOR_INT64 ) {
1612
1630
uint64_t a = (uint64_t ) term_maybe_unbox_int64 (arg1 );
1613
- int64_t result = ( int64_t ) ( a >> b ); //FIX THIS
1631
+ int64_t result = int64_bsr_safe ( a , b );
1614
1632
1615
1633
#if BOXED_TERMS_REQUIRED_FOR_INT64 > 1
1616
1634
return make_maybe_boxed_int64 (ctx , fail_label , live , result );
0 commit comments