Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5be304b0
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5be304b0
编写于
3月 17, 2020
作者:
R
Ralf Jung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
miri: simplify shift operator overflow checking
上级
cdb50c6f
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
13 addition
and
12 deletion
+13
-12
src/librustc_mir/interpret/operator.rs
src/librustc_mir/interpret/operator.rs
+13
-12
未找到文件。
src/librustc_mir/interpret/operator.rs
浏览文件 @
5be304b0
use
std
::
convert
::
TryFrom
;
use
rustc
::
mir
;
use
rustc
::
mir
::
interpret
::{
InterpResult
,
Scalar
};
use
rustc
::
ty
::{
...
...
@@ -130,28 +132,27 @@ fn binary_int_op(
// Shift ops can have an RHS with a different numeric type.
if
bin_op
==
Shl
||
bin_op
==
Shr
{
let
signed
=
left_layout
.abi
.is_signed
();
let
mut
oflo
=
(
r
as
u32
as
u128
)
!=
r
;
let
mut
r
=
r
as
u32
;
let
size
=
left_layout
.size
;
oflo
|
=
r
>=
size
.bits
()
as
u32
;
r
%=
size
.bits
()
as
u32
;
let
size
=
u128
::
from
(
left_layout
.size
.bits
());
let
overflow
=
r
>=
size
;
let
r
=
r
%
size
;
// mask to type size
let
r
=
u32
::
try_from
(
r
)
.unwrap
();
// we masked so this will always fit
let
result
=
if
signed
{
let
l
=
self
.sign_extend
(
l
,
left_layout
)
as
i128
;
let
result
=
match
bin_op
{
Shl
=>
l
<<
r
,
Shr
=>
l
>>
r
,
Shl
=>
l
.checked_shl
(
r
)
.unwrap
()
,
Shr
=>
l
.checked_shr
(
r
)
.unwrap
()
,
_
=>
bug!
(
"it has already been checked that this is a shift op"
),
};
result
as
u128
}
else
{
match
bin_op
{
Shl
=>
l
<<
r
,
Shr
=>
l
>>
r
,
Shl
=>
l
.checked_shl
(
r
)
.unwrap
()
,
Shr
=>
l
.checked_shr
(
r
)
.unwrap
()
,
_
=>
bug!
(
"it has already been checked that this is a shift op"
),
}
};
let
truncated
=
self
.truncate
(
result
,
left_layout
);
return
Ok
((
Scalar
::
from_uint
(
truncated
,
size
),
oflo
,
left_layout
.ty
));
return
Ok
((
Scalar
::
from_uint
(
truncated
,
left_layout
.size
),
overflow
,
left_layout
.ty
));
}
// For the remaining ops, the types must be the same on both sides
...
...
@@ -193,7 +194,6 @@ fn binary_int_op(
_
=>
None
,
};
if
let
Some
(
op
)
=
op
{
let
l128
=
self
.sign_extend
(
l
,
left_layout
)
as
i128
;
let
r
=
self
.sign_extend
(
r
,
right_layout
)
as
i128
;
// We need a special check for overflowing remainder:
// "int_min % -1" overflows and returns 0, but after casting things to a larger int
...
...
@@ -206,8 +206,9 @@ fn binary_int_op(
}
_
=>
{}
}
let
l
=
self
.sign_extend
(
l
,
left_layout
)
as
i128
;
let
(
result
,
oflo
)
=
op
(
l
128
,
r
);
let
(
result
,
oflo
)
=
op
(
l
,
r
);
// This may be out-of-bounds for the result type, so we have to truncate ourselves.
// If that truncation loses any information, we have an overflow.
let
result
=
result
as
u128
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录