@@ -938,10 +938,10 @@ impl<'c> Translation<'c> {
938938 // In this translation, there are only pointers to functions and
939939 // & becomes a no-op when applied to a function.
940940
941- let arg = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
941+ let val = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
942942
943943 if self . ast_context . is_function_pointer ( ctype) {
944- Ok ( arg . map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) )
944+ Ok ( val . map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) )
945945 } else {
946946 let pointee_ty =
947947 self . ast_context
@@ -950,13 +950,57 @@ impl<'c> Translation<'c> {
950950 TranslationError :: generic ( "Address-of should return a pointer" )
951951 } ) ?;
952952
953+ let expr_kind = & self . ast_context . index ( arg) . kind ;
954+ let translate_as_macro = self
955+ . convert_const_macro_expansion ( ctx, arg, None )
956+ . ok ( )
957+ . flatten ( )
958+ . is_some ( ) ;
959+
960+ // String literals are translated with a transmute, which produces a temporary.
961+ // Taking the address of a temporary leaves a dangling pointer. So instead,
962+ // cast the string literal directly so that its 'static lifetime is preserved.
963+ if let (
964+ & CExprKind :: Literal (
965+ literal_cqual_type,
966+ CLiteral :: String ( ref bytes, element_size @ 1 ) ,
967+ ) ,
968+ false ,
969+ ) = ( expr_kind, translate_as_macro)
970+ {
971+ let num_elems =
972+ match self . ast_context . resolve_type ( literal_cqual_type. ctype ) . kind {
973+ CTypeKind :: ConstantArray ( _, num_elems) => num_elems,
974+ ref kind => {
975+ panic ! (
976+ "String literal with unknown size: {bytes:?}, kind = {kind:?}"
977+ )
978+ }
979+ } ;
980+
981+ // Match the literal size to the expected size padding with zeros as needed
982+ let size = num_elems * ( element_size as usize ) ;
983+ let mut bytes_padded = Vec :: with_capacity ( size) ;
984+ bytes_padded. extend ( bytes) ;
985+ bytes_padded. resize ( size, 0 ) ;
986+
987+ let array_ty = mk ( ) . array_ty (
988+ mk ( ) . ident_ty ( "u8" ) ,
989+ mk ( ) . lit_expr ( bytes_padded. len ( ) as u128 ) ,
990+ ) ;
991+ let bytes_literal = mk ( ) . lit_expr ( bytes_padded) ;
992+ let val = mk ( ) . cast_expr ( bytes_literal, mk ( ) . ptr_ty ( array_ty) ) ;
993+ let val = mk ( ) . cast_expr ( val, ty) ;
994+ return Ok ( WithStmts :: new_val ( val) ) ;
995+ }
996+
953997 let mutbl = if pointee_ty. qualifiers . is_const {
954998 Mutability :: Immutable
955999 } else {
9561000 Mutability :: Mutable
9571001 } ;
9581002
959- arg . result_map ( |a| {
1003+ val . result_map ( |a| {
9601004 let mut addr_of_arg: Box < Expr > ;
9611005
9621006 if ctx. is_static {
0 commit comments