@@ -2158,7 +2158,7 @@ impl<'c> Translation<'c> {
2158
2158
ctx : ExprContext ,
2159
2159
expansions : & [ CExprId ] ,
2160
2160
) -> TranslationResult < ( Box < Expr > , CTypeId ) > {
2161
- let ( mut val, ty) = expansions
2161
+ let ( val, ty) = expansions
2162
2162
. iter ( )
2163
2163
. try_fold :: < Option < ( WithStmts < Box < Expr > > , CTypeId ) > , _ , _ > ( None , |canonical, & id| {
2164
2164
self . can_convert_const_macro_expansion ( id) ?;
@@ -2195,7 +2195,6 @@ impl<'c> Translation<'c> {
2195
2195
} ) ?
2196
2196
. ok_or_else ( || format_err ! ( "Could not find a valid type for macro" ) ) ?;
2197
2197
2198
- val. set_unsafe ( ) ;
2199
2198
val. to_unsafe_pure_expr ( )
2200
2199
. map ( |val| ( val, ty) )
2201
2200
. ok_or_else ( || TranslationError :: generic ( "Macro expansion is not a pure expression" ) )
@@ -2701,7 +2700,15 @@ impl<'c> Translation<'c> {
2701
2700
let mut init = init?;
2702
2701
2703
2702
stmts. append ( init. stmts_mut ( ) ) ;
2704
- let init = init. into_value ( ) ;
2703
+ // A `const` context is not "already unsafe" the way code within a `fn` is
2704
+ // (since we translate all `fn`s as `unsafe`). Therefore, in `const` contexts,
2705
+ // expose any underlying unsafety in the initializer with an `unsafe` block.
2706
+ let init = if ctx. is_const {
2707
+ init. to_unsafe_pure_expr ( )
2708
+ . expect ( "init should not have any statements" )
2709
+ } else {
2710
+ init. into_value ( )
2711
+ } ;
2705
2712
2706
2713
let zeroed = self . implicit_default_expr ( typ. ctype , false ) ?;
2707
2714
let zeroed = if ctx. is_const {
@@ -3756,21 +3763,26 @@ impl<'c> Translation<'c> {
3756
3763
} ;
3757
3764
3758
3765
let lhs = self . convert_expr ( ctx. used ( ) , arr, None ) ?;
3759
- Ok ( lhs. map ( |lhs| {
3766
+ lhs. and_then ( |lhs| {
3760
3767
// stmts.extend(lhs.stmts_mut());
3761
3768
// is_unsafe = is_unsafe || lhs.is_unsafe();
3762
3769
3763
3770
// Don't dereference the offset if we're still within the variable portion
3764
3771
if let Some ( elt_type_id) = var_elt_type_id {
3765
3772
let mul = self . compute_size_of_expr ( elt_type_id) ;
3766
- pointer_offset ( lhs, rhs, mul, false , true )
3773
+ Ok ( WithStmts :: new_unsafe_val ( pointer_offset (
3774
+ lhs, rhs, mul, false , true ,
3775
+ ) ) )
3767
3776
} else {
3768
- mk ( ) . index_expr ( lhs, cast_int ( rhs, "usize" , false ) )
3777
+ Ok ( WithStmts :: new_val (
3778
+ mk ( ) . index_expr ( lhs, cast_int ( rhs, "usize" , false ) ) ,
3779
+ ) )
3769
3780
}
3770
- } ) )
3781
+ } )
3771
3782
} else {
3772
3783
// LHS must be ref decayed for the offset method call's self param
3773
- let lhs = self . convert_expr ( ctx. used ( ) . decay_ref ( ) , * lhs, None ) ?;
3784
+ let mut lhs = self . convert_expr ( ctx. used ( ) . decay_ref ( ) , * lhs, None ) ?;
3785
+ lhs. set_unsafe ( ) ; // `pointer_offset` is unsafe.
3774
3786
lhs. result_map ( |lhs| {
3775
3787
// stmts.extend(lhs.stmts_mut());
3776
3788
// is_unsafe = is_unsafe || lhs.is_unsafe();
@@ -3838,7 +3850,7 @@ impl<'c> Translation<'c> {
3838
3850
3839
3851
// Function pointer call
3840
3852
_ => {
3841
- let callee = self . convert_expr ( ctx. used ( ) , func, None ) ?;
3853
+ let mut callee = self . convert_expr ( ctx. used ( ) , func, None ) ?;
3842
3854
let make_fn_ty = |ret_ty : Box < Type > | {
3843
3855
let ret_ty = match * ret_ty {
3844
3856
Type :: Tuple ( TypeTuple { elems : ref v, .. } ) if v. is_empty ( ) => ReturnType :: Default ,
@@ -3856,6 +3868,7 @@ impl<'c> Translation<'c> {
3856
3868
// K&R function pointer without arguments
3857
3869
let ret_ty = self . convert_type ( ret_ty. ctype ) ?;
3858
3870
let target_ty = make_fn_ty ( ret_ty) ;
3871
+ callee. set_unsafe ( ) ;
3859
3872
callee. map ( |fn_ptr| {
3860
3873
let fn_ptr = unwrap_function_pointer ( fn_ptr) ;
3861
3874
transmute_expr ( mk ( ) . infer_ty ( ) , target_ty, fn_ptr)
@@ -3865,6 +3878,7 @@ impl<'c> Translation<'c> {
3865
3878
// We have to infer the return type from our expression type
3866
3879
let ret_ty = self . convert_type ( call_expr_ty. ctype ) ?;
3867
3880
let target_ty = make_fn_ty ( ret_ty) ;
3881
+ callee. set_unsafe ( ) ;
3868
3882
callee. map ( |fn_ptr| {
3869
3883
transmute_expr ( mk ( ) . infer_ty ( ) , target_ty, fn_ptr)
3870
3884
} )
0 commit comments