Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e6a5a941
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,发现更多精彩内容 >>
提交
e6a5a941
编写于
8月 26, 2018
作者:
R
Ralf Jung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
restructure unary_op to also dispatch on type first; fix promotion with unary '-' overflowing
上级
066d2eea
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
62 addition
and
42 deletion
+62
-42
src/librustc_mir/interpret/operator.rs
src/librustc_mir/interpret/operator.rs
+54
-42
src/test/run-pass/ctfe/promotion.rs
src/test/run-pass/ctfe/promotion.rs
+8
-0
未找到文件。
src/librustc_mir/interpret/operator.rs
浏览文件 @
e6a5a941
...
...
@@ -302,38 +302,33 @@ pub fn binary_op(
let
right
=
right
.to_scalar
()
?
;
trace!
(
"Running binary op {:?}: {:?} ({:?}), {:?} ({:?})"
,
bin_op
,
left
,
left_layout
.ty
.sty
,
right
,
right_layout
.ty.s
ty
);
bin_op
,
left
,
left_layout
.ty
,
right
,
right_layout
.
ty
);
match
left_layout
.ty.sty
{
ty
::
Char
=>
{
assert_eq!
(
left_layout
.ty
,
right_layout
.ty
);
let
l
=
left
.to_char
()
?
;
let
r
=
right
.to_char
()
?
;
self
.binary_char_op
(
bin_op
,
l
,
r
)
let
l
eft
=
left
.to_char
()
?
;
let
r
ight
=
right
.to_char
()
?
;
self
.binary_char_op
(
bin_op
,
l
eft
,
right
)
}
ty
::
Bool
=>
{
assert_eq!
(
left_layout
.ty
,
right_layout
.ty
);
let
l
=
left
.to_bool
()
?
;
let
r
=
right
.to_bool
()
?
;
self
.binary_bool_op
(
bin_op
,
l
,
r
)
let
l
eft
=
left
.to_bool
()
?
;
let
r
ight
=
right
.to_bool
()
?
;
self
.binary_bool_op
(
bin_op
,
l
eft
,
right
)
}
ty
::
Float
(
fty
)
=>
{
assert_eq!
(
left_layout
.ty
,
right_layout
.ty
);
let
l
=
left
.to_bits
(
left_layout
.size
)
?
;
let
r
=
right
.to_bits
(
right_layout
.size
)
?
;
self
.binary_float_op
(
bin_op
,
fty
,
l
,
r
)
let
l
eft
=
left
.to_bits
(
left_layout
.size
)
?
;
let
r
ight
=
right
.to_bits
(
right_layout
.size
)
?
;
self
.binary_float_op
(
bin_op
,
fty
,
l
eft
,
right
)
}
_
=>
{
// Must be integer(-like) types
#[inline]
fn
is_ptr
<
'tcx
>
(
ty
:
ty
::
Ty
<
'tcx
>
)
->
bool
{
match
ty
.sty
{
ty
::
RawPtr
(
..
)
|
ty
::
Ref
(
..
)
|
ty
::
FnPtr
(
..
)
=>
true
,
_
=>
false
,
}
}
assert
!
(
left_layout
.ty
.is_integral
()
||
is_ptr
(
left_layout
.ty
));
assert
!
(
right_layout
.ty
.is_integral
()
||
is_ptr
(
right_layout
.ty
));
// Must be integer(-like) types. Don't forget about == on fn pointers.
assert
!
(
left_layout
.ty
.is_integral
()
||
left_layout
.ty
.is_unsafe_ptr
()
||
left_layout
.ty
.is_fn
());
assert
!
(
right_layout
.ty
.is_integral
()
||
right_layout
.ty
.is_unsafe_ptr
()
||
right_layout
.ty
.is_fn
());
// Handle operations that support pointer values
if
let
Some
(
handled
)
=
...
...
@@ -343,9 +338,9 @@ fn is_ptr<'tcx>(ty: ty::Ty<'tcx>) -> bool {
}
// Everything else only works with "proper" bits
let
l
=
left
.to_bits
(
left_layout
.size
)
?
;
let
r
=
right
.to_bits
(
right_layout
.size
)
?
;
self
.binary_int_op
(
bin_op
,
l
,
left_layout
,
r
,
right_layout
)
let
l
eft
=
left
.to_bits
(
left_layout
.size
)
?
;
let
r
ight
=
right
.to_bits
(
right_layout
.size
)
?
;
self
.binary_int_op
(
bin_op
,
l
eft
,
left_layout
,
right
,
right_layout
)
}
}
}
...
...
@@ -360,25 +355,42 @@ pub fn unary_op(
use
rustc_apfloat
::
ieee
::{
Single
,
Double
};
use
rustc_apfloat
::
Float
;
let
size
=
layout
.size
;
let
bytes
=
val
.to_bits
(
size
)
?
;
let
result_bytes
=
match
(
un_op
,
&
layout
.ty.sty
)
{
(
Not
,
ty
::
Bool
)
=>
!
val
.to_bool
()
?
as
u128
,
(
Not
,
_
)
=>
!
bytes
,
trace!
(
"Running unary op {:?}: {:?} ({:?})"
,
un_op
,
val
,
layout
.ty.sty
);
(
Neg
,
ty
::
Float
(
FloatTy
::
F32
))
=>
Single
::
to_bits
(
-
Single
::
from_bits
(
bytes
)),
(
Neg
,
ty
::
Float
(
FloatTy
::
F64
))
=>
Double
::
to_bits
(
-
Double
::
from_bits
(
bytes
)),
(
Neg
,
_
)
if
bytes
==
(
1
<<
(
size
.bits
()
-
1
))
=>
return
err!
(
OverflowNeg
),
(
Neg
,
_
)
=>
(
-
(
bytes
as
i128
))
as
u128
,
};
Ok
(
Scalar
::
Bits
{
bits
:
self
.truncate
(
result_bytes
,
layout
),
size
:
size
.bytes
()
as
u8
,
})
match
layout
.ty.sty
{
ty
::
Bool
=>
{
let
val
=
val
.to_bool
()
?
;
let
res
=
match
un_op
{
Not
=>
!
val
,
_
=>
bug!
(
"Invalid bool op {:?}"
,
un_op
)
};
Ok
(
Scalar
::
from_bool
(
res
))
}
ty
::
Float
(
fty
)
=>
{
let
val
=
val
.to_bits
(
layout
.size
)
?
;
let
res
=
match
(
un_op
,
fty
)
{
(
Neg
,
FloatTy
::
F32
)
=>
Single
::
to_bits
(
-
Single
::
from_bits
(
val
)),
(
Neg
,
FloatTy
::
F64
)
=>
Double
::
to_bits
(
-
Double
::
from_bits
(
val
)),
_
=>
bug!
(
"Invalid float op {:?}"
,
un_op
)
};
Ok
(
Scalar
::
Bits
{
bits
:
res
,
size
:
layout
.size
.bytes
()
as
u8
})
}
_
=>
{
assert
!
(
layout
.ty
.is_integral
());
let
val
=
val
.to_bits
(
layout
.size
)
?
;
let
res
=
match
un_op
{
Not
=>
!
val
,
Neg
=>
{
assert
!
(
layout
.abi
.is_signed
());
(
-
(
val
as
i128
))
as
u128
}
};
// res needs tuncating
Ok
(
Scalar
::
Bits
{
bits
:
self
.truncate
(
res
,
layout
),
size
:
layout
.size
.bytes
()
as
u8
,
})
}
}
}
}
src/test/run-pass/ctfe/promotion.rs
浏览文件 @
e6a5a941
...
...
@@ -8,10 +8,18 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -O
fn
foo
(
_
:
&
'static
[
&
'static
str
])
{}
fn
bar
(
_
:
&
'static
[
&
'static
str
;
3
])
{}
fn
baz_i32
(
_
:
&
'static
i32
)
{}
fn
baz_u32
(
_
:
&
'static
u32
)
{}
fn
main
()
{
foo
(
&
[
"a"
,
"b"
,
"c"
]);
bar
(
&
[
"d"
,
"e"
,
"f"
]);
// make sure that these do not cause trouble despite overflowing
baz_u32
(
&
(
0
-
1
));
baz_i32
(
&-
std
::
i32
::
MIN
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录