@@ -901,6 +901,7 @@ impl<'c> Translation<'c> {
901901 lrvalue : LRValue ,
902902 ) -> TranslationResult < WithStmts < Box < Expr > > > {
903903 let CQualTypeId { ctype, .. } = cqual_type;
904+ let ty = self . convert_type ( ctype) ?;
904905 let resolved_ctype = self . ast_context . resolve_type ( ctype) ;
905906
906907 let mut unary = match name {
@@ -923,27 +924,54 @@ impl<'c> Translation<'c> {
923924 // In this translation, there are only pointers to functions and
924925 // & becomes a no-op when applied to a function.
925926
926- let arg = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
927+ let val = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
927928
928929 if self . ast_context . is_function_pointer ( ctype) {
929- Ok ( arg. map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) )
930+ return Ok ( val. map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) ) ;
931+ }
932+
933+ let pointee_ty =
934+ self . ast_context
935+ . get_pointee_qual_type ( ctype)
936+ . ok_or_else ( || {
937+ TranslationError :: generic ( "Address-of should return a pointer" )
938+ } ) ?;
939+
940+ let mutbl = if pointee_ty. qualifiers . is_const {
941+ Mutability :: Immutable
930942 } else {
931- let pointee_ty =
932- self . ast_context
933- . get_pointee_qual_type ( ctype)
934- . ok_or_else ( || {
935- TranslationError :: generic ( "Address-of should return a pointer" )
936- } ) ?;
937-
938- let mutbl = if pointee_ty. qualifiers . is_const {
939- Mutability :: Immutable
943+ Mutability :: Mutable
944+ } ;
945+
946+ Ok ( val. map ( |mut val| {
947+ if matches ! (
948+ arg_kind,
949+ CExprKind :: Literal ( ..) | CExprKind :: CompoundLiteral ( ..)
950+ ) {
951+ // Rust does not extend the lifetime of temporaries with a raw borrow,
952+ // but will do so with a regular borrow.
953+ val = mk ( ) . set_mutbl ( mutbl) . borrow_expr ( val) ;
954+
955+ if ctx. decay_ref . is_yes ( ) {
956+ val = mk ( ) . cast_expr ( val, ty)
957+ }
940958 } else {
941- Mutability :: Mutable
942- } ;
959+ self . use_feature ( "raw_ref_op" ) ;
960+
961+ // TODO: The currently used nightly doesn't allow `&raw mut` in
962+ // static initialisers, but it's allowed since version 1.83.
963+ // So we take a `&raw const` and then cast.
964+ // Remove this exemption when the version is updated.
965+ if ctx. is_static && matches ! ( mutbl, Mutability :: Mutable ) {
966+ val = mk ( ) . raw_borrow_expr ( val) ;
967+ val = mk ( ) . cast_expr ( val, ty) ;
968+ } else {
969+ val = mk ( ) . set_mutbl ( mutbl) . raw_borrow_expr ( val) ;
970+ }
971+ }
943972
944- self . use_feature ( "raw_ref_op" ) ;
945- Ok ( arg. map ( |a| mk ( ) . set_mutbl ( mutbl) . raw_borrow_expr ( a) ) )
946- }
973+ val
974+ } ) )
947975 }
948976 c_ast:: UnOp :: PreIncrement => self . convert_pre_increment ( ctx, cqual_type, true , arg) ,
949977 c_ast:: UnOp :: PreDecrement => self . convert_pre_increment ( ctx, cqual_type, false , arg) ,
0 commit comments