@@ -210,133 +210,111 @@ pub(crate) unsafe fn create_module<'ll>(
210210    // If skipping the PLT is enabled, we need to add some module metadata 
211211    // to ensure intrinsic calls don't use it. 
212212    if  !sess. needs_plt ( )  { 
213-         let  avoid_plt = c"RtLibUseGOT" . as_ptr ( ) ; 
214-         unsafe  { 
215-             llvm:: LLVMRustAddModuleFlagU32 ( llmod,  llvm:: LLVMModFlagBehavior :: Warning ,  avoid_plt,  1 ) ; 
216-         } 
213+         llvm:: add_module_flag_u32 ( llmod,  llvm:: ModuleFlagMergeBehavior :: Warning ,  "RtLibUseGOT" ,  1 ) ; 
217214    } 
218215
219216    // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.) 
220217    if  sess. is_sanitizer_cfi_canonical_jump_tables_enabled ( )  && sess. is_sanitizer_cfi_enabled ( )  { 
221-         let  canonical_jump_tables = c"CFI Canonical Jump Tables" . as_ptr ( ) ; 
222-         unsafe  { 
223-             llvm:: LLVMRustAddModuleFlagU32 ( 
224-                 llmod, 
225-                 llvm:: LLVMModFlagBehavior :: Override , 
226-                 canonical_jump_tables, 
227-                 1 , 
228-             ) ; 
229-         } 
218+         llvm:: add_module_flag_u32 ( 
219+             llmod, 
220+             llvm:: ModuleFlagMergeBehavior :: Override , 
221+             "CFI Canonical Jump Tables" , 
222+             1 , 
223+         ) ; 
230224    } 
231225
232226    // If we're normalizing integers with CFI, ensure LLVM generated functions do the same. 
233227    // See https://github.com/llvm/llvm-project/pull/104826 
234228    if  sess. is_sanitizer_cfi_normalize_integers_enabled ( )  { 
235-         let  cfi_normalize_integers = c"cfi-normalize-integers" . as_ptr ( ) ; 
236-         unsafe  { 
237-             llvm:: LLVMRustAddModuleFlagU32 ( 
238-                 llmod, 
239-                 llvm:: LLVMModFlagBehavior :: Override , 
240-                 cfi_normalize_integers, 
241-                 1 , 
242-             ) ; 
243-         } 
229+         llvm:: add_module_flag_u32 ( 
230+             llmod, 
231+             llvm:: ModuleFlagMergeBehavior :: Override , 
232+             "cfi-normalize-integers" , 
233+             1 , 
234+         ) ; 
244235    } 
245236
246237    // Enable LTO unit splitting if specified or if CFI is enabled. (See 
247238    // https://reviews.llvm.org/D53891.) 
248239    if  sess. is_split_lto_unit_enabled ( )  || sess. is_sanitizer_cfi_enabled ( )  { 
249-         let  enable_split_lto_unit = c"EnableSplitLTOUnit" . as_ptr ( ) ; 
250-         unsafe  { 
251-             llvm:: LLVMRustAddModuleFlagU32 ( 
252-                 llmod, 
253-                 llvm:: LLVMModFlagBehavior :: Override , 
254-                 enable_split_lto_unit, 
255-                 1 , 
256-             ) ; 
257-         } 
240+         llvm:: add_module_flag_u32 ( 
241+             llmod, 
242+             llvm:: ModuleFlagMergeBehavior :: Override , 
243+             "EnableSplitLTOUnit" , 
244+             1 , 
245+         ) ; 
258246    } 
259247
260248    // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.) 
261249    if  sess. is_sanitizer_kcfi_enabled ( )  { 
262-         let  kcfi = c"kcfi" . as_ptr ( ) ; 
263-         unsafe  { 
264-             llvm:: LLVMRustAddModuleFlagU32 ( llmod,  llvm:: LLVMModFlagBehavior :: Override ,  kcfi,  1 ) ; 
265-         } 
250+         llvm:: add_module_flag_u32 ( llmod,  llvm:: ModuleFlagMergeBehavior :: Override ,  "kcfi" ,  1 ) ; 
266251
267252        // Add "kcfi-offset" module flag with -Z patchable-function-entry (See 
268253        // https://reviews.llvm.org/D141172). 
269254        let  pfe =
270255            PatchableFunctionEntry :: from_config ( sess. opts . unstable_opts . patchable_function_entry ) ; 
271256        if  pfe. prefix ( )  > 0  { 
272-             let  kcfi_offset = c"kcfi-offset" . as_ptr ( ) ; 
273-             unsafe  { 
274-                 llvm:: LLVMRustAddModuleFlagU32 ( 
275-                     llmod, 
276-                     llvm:: LLVMModFlagBehavior :: Override , 
277-                     kcfi_offset, 
278-                     pfe. prefix ( ) . into ( ) , 
279-                 ) ; 
280-             } 
257+             llvm:: add_module_flag_u32 ( 
258+                 llmod, 
259+                 llvm:: ModuleFlagMergeBehavior :: Override , 
260+                 "kcfi-offset" , 
261+                 pfe. prefix ( ) . into ( ) , 
262+             ) ; 
281263        } 
282264    } 
283265
284266    // Control Flow Guard is currently only supported by the MSVC linker on Windows. 
285267    if  sess. target . is_like_msvc  { 
286-         unsafe  { 
287-             match  sess. opts . cg . control_flow_guard  { 
288-                 CFGuard :: Disabled  => { } 
289-                 CFGuard :: NoChecks  => { 
290-                     // Set `cfguard=1` module flag to emit metadata only. 
291-                     llvm:: LLVMRustAddModuleFlagU32 ( 
292-                         llmod, 
293-                         llvm:: LLVMModFlagBehavior :: Warning , 
294-                         c"cfguard" . as_ptr ( )  as  * const  _ , 
295-                         1 , 
296-                     ) 
297-                 } 
298-                 CFGuard :: Checks  => { 
299-                     // Set `cfguard=2` module flag to emit metadata and checks. 
300-                     llvm:: LLVMRustAddModuleFlagU32 ( 
301-                         llmod, 
302-                         llvm:: LLVMModFlagBehavior :: Warning , 
303-                         c"cfguard" . as_ptr ( )  as  * const  _ , 
304-                         2 , 
305-                     ) 
306-                 } 
268+         match  sess. opts . cg . control_flow_guard  { 
269+             CFGuard :: Disabled  => { } 
270+             CFGuard :: NoChecks  => { 
271+                 // Set `cfguard=1` module flag to emit metadata only. 
272+                 llvm:: add_module_flag_u32 ( 
273+                     llmod, 
274+                     llvm:: ModuleFlagMergeBehavior :: Warning , 
275+                     "cfguard" , 
276+                     1 , 
277+                 ) ; 
278+             } 
279+             CFGuard :: Checks  => { 
280+                 // Set `cfguard=2` module flag to emit metadata and checks. 
281+                 llvm:: add_module_flag_u32 ( 
282+                     llmod, 
283+                     llvm:: ModuleFlagMergeBehavior :: Warning , 
284+                     "cfguard" , 
285+                     2 , 
286+                 ) ; 
307287            } 
308288        } 
309289    } 
310290
311291    if  let  Some ( BranchProtection  {  bti,  pac_ret } )  = sess. opts . unstable_opts . branch_protection  { 
312292        if  sess. target . arch  == "aarch64"  { 
313-             unsafe  { 
314-                 llvm:: LLVMRustAddModuleFlagU32 ( 
315-                     llmod, 
316-                     llvm:: LLVMModFlagBehavior :: Min , 
317-                     c"branch-target-enforcement" . as_ptr ( ) , 
318-                     bti. into ( ) , 
319-                 ) ; 
320-                 llvm:: LLVMRustAddModuleFlagU32 ( 
321-                     llmod, 
322-                     llvm:: LLVMModFlagBehavior :: Min , 
323-                     c"sign-return-address" . as_ptr ( ) , 
324-                     pac_ret. is_some ( ) . into ( ) , 
325-                 ) ; 
326-                 let  pac_opts = pac_ret. unwrap_or ( PacRet  {  leaf :  false ,  key :  PAuthKey :: A  } ) ; 
327-                 llvm:: LLVMRustAddModuleFlagU32 ( 
328-                     llmod, 
329-                     llvm:: LLVMModFlagBehavior :: Min , 
330-                     c"sign-return-address-all" . as_ptr ( ) , 
331-                     pac_opts. leaf . into ( ) , 
332-                 ) ; 
333-                 llvm:: LLVMRustAddModuleFlagU32 ( 
334-                     llmod, 
335-                     llvm:: LLVMModFlagBehavior :: Min , 
336-                     c"sign-return-address-with-bkey" . as_ptr ( ) , 
337-                     u32:: from ( pac_opts. key  == PAuthKey :: B ) , 
338-                 ) ; 
339-             } 
293+             llvm:: add_module_flag_u32 ( 
294+                 llmod, 
295+                 llvm:: ModuleFlagMergeBehavior :: Min , 
296+                 "branch-target-enforcement" , 
297+                 bti. into ( ) , 
298+             ) ; 
299+             llvm:: add_module_flag_u32 ( 
300+                 llmod, 
301+                 llvm:: ModuleFlagMergeBehavior :: Min , 
302+                 "sign-return-address" , 
303+                 pac_ret. is_some ( ) . into ( ) , 
304+             ) ; 
305+             let  pac_opts = pac_ret. unwrap_or ( PacRet  {  leaf :  false ,  key :  PAuthKey :: A  } ) ; 
306+             llvm:: add_module_flag_u32 ( 
307+                 llmod, 
308+                 llvm:: ModuleFlagMergeBehavior :: Min , 
309+                 "sign-return-address-all" , 
310+                 pac_opts. leaf . into ( ) , 
311+             ) ; 
312+             llvm:: add_module_flag_u32 ( 
313+                 llmod, 
314+                 llvm:: ModuleFlagMergeBehavior :: Min , 
315+                 "sign-return-address-with-bkey" , 
316+                 u32:: from ( pac_opts. key  == PAuthKey :: B ) , 
317+             ) ; 
340318        }  else  { 
341319            bug ! ( 
342320                "branch-protection used on non-AArch64 target; \  
@@ -347,75 +325,59 @@ pub(crate) unsafe fn create_module<'ll>(
347325
348326    // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang). 
349327    if  let  CFProtection :: Branch  | CFProtection :: Full  = sess. opts . unstable_opts . cf_protection  { 
350-         unsafe  { 
351-             llvm:: LLVMRustAddModuleFlagU32 ( 
352-                 llmod, 
353-                 llvm:: LLVMModFlagBehavior :: Override , 
354-                 c"cf-protection-branch" . as_ptr ( ) , 
355-                 1 , 
356-             ) ; 
357-         } 
328+         llvm:: add_module_flag_u32 ( 
329+             llmod, 
330+             llvm:: ModuleFlagMergeBehavior :: Override , 
331+             "cf-protection-branch" , 
332+             1 , 
333+         ) ; 
358334    } 
359335    if  let  CFProtection :: Return  | CFProtection :: Full  = sess. opts . unstable_opts . cf_protection  { 
360-         unsafe  { 
361-             llvm:: LLVMRustAddModuleFlagU32 ( 
362-                 llmod, 
363-                 llvm:: LLVMModFlagBehavior :: Override , 
364-                 c"cf-protection-return" . as_ptr ( ) , 
365-                 1 , 
366-             ) ; 
367-         } 
336+         llvm:: add_module_flag_u32 ( 
337+             llmod, 
338+             llvm:: ModuleFlagMergeBehavior :: Override , 
339+             "cf-protection-return" , 
340+             1 , 
341+         ) ; 
368342    } 
369343
370344    if  sess. opts . unstable_opts . virtual_function_elimination  { 
371-         unsafe  { 
372-             llvm:: LLVMRustAddModuleFlagU32 ( 
373-                 llmod, 
374-                 llvm:: LLVMModFlagBehavior :: Error , 
375-                 c"Virtual Function Elim" . as_ptr ( ) , 
376-                 1 , 
377-             ) ; 
378-         } 
345+         llvm:: add_module_flag_u32 ( 
346+             llmod, 
347+             llvm:: ModuleFlagMergeBehavior :: Error , 
348+             "Virtual Function Elim" , 
349+             1 , 
350+         ) ; 
379351    } 
380352
381353    // Set module flag to enable Windows EHCont Guard (/guard:ehcont). 
382354    if  sess. opts . unstable_opts . ehcont_guard  { 
383-         unsafe  { 
384-             llvm:: LLVMRustAddModuleFlagU32 ( 
385-                 llmod, 
386-                 llvm:: LLVMModFlagBehavior :: Warning , 
387-                 c"ehcontguard" . as_ptr ( )  as  * const  _ , 
388-                 1 , 
389-             ) 
390-         } 
355+         llvm:: add_module_flag_u32 ( llmod,  llvm:: ModuleFlagMergeBehavior :: Warning ,  "ehcontguard" ,  1 ) ; 
391356    } 
392357
393358    match  sess. opts . unstable_opts . function_return  { 
394359        FunctionReturn :: Keep  => { } 
395-         FunctionReturn :: ThunkExtern  => unsafe   { 
396-             llvm:: LLVMRustAddModuleFlagU32 ( 
360+         FunctionReturn :: ThunkExtern  => { 
361+             llvm:: add_module_flag_u32 ( 
397362                llmod, 
398-                 llvm:: LLVMModFlagBehavior :: Override , 
399-                 c "function_return_thunk_extern". as_ptr ( ) , 
363+                 llvm:: ModuleFlagMergeBehavior :: Override , 
364+                 "function_return_thunk_extern" , 
400365                1 , 
401-             ) 
402-         } , 
366+             ) ; 
367+         } 
403368    } 
404369
405370    match  ( sess. opts . unstable_opts . small_data_threshold ,  sess. target . small_data_threshold_support ( ) ) 
406371    { 
407372        // Set up the small-data optimization limit for architectures that use 
408373        // an LLVM module flag to control this. 
409374        ( Some ( threshold) ,  SmallDataThresholdSupport :: LlvmModuleFlag ( flag) )  => { 
410-             let  flag = SmallCStr :: new ( flag. as_ref ( ) ) ; 
411-             unsafe  { 
412-                 llvm:: LLVMRustAddModuleFlagU32 ( 
413-                     llmod, 
414-                     llvm:: LLVMModFlagBehavior :: Error , 
415-                     flag. as_c_str ( ) . as_ptr ( ) , 
416-                     threshold as  u32 , 
417-                 ) 
418-             } 
375+             llvm:: add_module_flag_u32 ( 
376+                 llmod, 
377+                 llvm:: ModuleFlagMergeBehavior :: Error , 
378+                 & flag, 
379+                 threshold as  u32 , 
380+             ) ; 
419381        } 
420382        _ => ( ) , 
421383    } ; 
@@ -449,33 +411,29 @@ pub(crate) unsafe fn create_module<'ll>(
449411    // If llvm_abiname is empty, emit nothing. 
450412    let  llvm_abiname = & sess. target . options . llvm_abiname ; 
451413    if  matches ! ( sess. target. arch. as_ref( ) ,  "riscv32"  | "riscv64" )  && !llvm_abiname. is_empty ( )  { 
452-         unsafe  { 
453-             llvm:: LLVMRustAddModuleFlagString ( 
454-                 llmod, 
455-                 llvm:: LLVMModFlagBehavior :: Error , 
456-                 c"target-abi" . as_ptr ( ) , 
457-                 llvm_abiname. as_c_char_ptr ( ) , 
458-                 llvm_abiname. len ( ) , 
459-             ) ; 
460-         } 
414+         llvm:: add_module_flag_str ( 
415+             llmod, 
416+             llvm:: ModuleFlagMergeBehavior :: Error , 
417+             "target-abi" , 
418+             llvm_abiname, 
419+         ) ; 
461420    } 
462421
463422    // Add module flags specified via -Z llvm_module_flag 
464-     for  ( key,  value,  behavior)  in  & sess. opts . unstable_opts . llvm_module_flag  { 
465-         let  key = format ! ( "{key}\0 " ) ; 
466-         let  behavior = match  behavior. as_str ( )  { 
467-             "error"  => llvm:: LLVMModFlagBehavior :: Error , 
468-             "warning"  => llvm:: LLVMModFlagBehavior :: Warning , 
469-             "require"  => llvm:: LLVMModFlagBehavior :: Require , 
470-             "override"  => llvm:: LLVMModFlagBehavior :: Override , 
471-             "append"  => llvm:: LLVMModFlagBehavior :: Append , 
472-             "appendunique"  => llvm:: LLVMModFlagBehavior :: AppendUnique , 
473-             "max"  => llvm:: LLVMModFlagBehavior :: Max , 
474-             "min"  => llvm:: LLVMModFlagBehavior :: Min , 
423+     for  ( key,  value,  merge_behavior)  in  & sess. opts . unstable_opts . llvm_module_flag  { 
424+         let  merge_behavior = match  merge_behavior. as_str ( )  { 
425+             "error"  => llvm:: ModuleFlagMergeBehavior :: Error , 
426+             "warning"  => llvm:: ModuleFlagMergeBehavior :: Warning , 
427+             "require"  => llvm:: ModuleFlagMergeBehavior :: Require , 
428+             "override"  => llvm:: ModuleFlagMergeBehavior :: Override , 
429+             "append"  => llvm:: ModuleFlagMergeBehavior :: Append , 
430+             "appendunique"  => llvm:: ModuleFlagMergeBehavior :: AppendUnique , 
431+             "max"  => llvm:: ModuleFlagMergeBehavior :: Max , 
432+             "min"  => llvm:: ModuleFlagMergeBehavior :: Min , 
475433            // We already checked this during option parsing 
476434            _ => unreachable ! ( ) , 
477435        } ; 
478-         unsafe   {   llvm:: LLVMRustAddModuleFlagU32 ( llmod,  behavior ,  key. as_c_char_ptr ( ) ,  * value)   } 
436+         llvm:: add_module_flag_u32 ( llmod,  merge_behavior ,  key,  * value) ; 
479437    } 
480438
481439    llmod
0 commit comments