@@ -177,32 +177,57 @@ impl<'a> Drop for StatRecorder<'a> {
177
177
}
178
178
179
179
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
180
- pub fn decl_fn ( llmod : ModuleRef , name : & str , cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
180
+ fn decl_fn ( llmod : ModuleRef , name : & str , cc : lib:: llvm:: CallConv ,
181
+ ty : Type , output : ty:: t ) -> ValueRef {
181
182
let llfn: ValueRef = name. with_c_str ( |buf| {
182
183
unsafe {
183
184
llvm:: LLVMGetOrInsertFunction ( llmod, buf, ty. to_ref ( ) )
184
185
}
185
186
} ) ;
186
187
188
+ match ty:: get ( output) . sty {
189
+ // functions returning bottom may unwind, but can never return normally
190
+ ty:: ty_bot => {
191
+ unsafe {
192
+ llvm:: LLVMAddFunctionAttr ( llfn, lib:: llvm:: NoReturnAttribute as c_uint )
193
+ }
194
+ }
195
+ // `~` pointer return values never alias because ownership is transferred
196
+ // FIXME #6750 ~Trait cannot be directly marked as
197
+ // noalias because the actual object pointer is nested.
198
+ ty:: ty_uniq( ..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
199
+ ty:: ty_vec( _, ty:: vstore_uniq) | ty:: ty_str( ty:: vstore_uniq) => {
200
+ unsafe {
201
+ llvm:: LLVMAddReturnAttribute ( llfn, lib:: llvm:: NoAliasAttribute as c_uint ) ;
202
+ }
203
+ }
204
+ _ => { }
205
+ }
206
+
187
207
lib:: llvm:: SetFunctionCallConv ( llfn, cc) ;
188
208
// Function addresses in Rust are never significant, allowing functions to be merged.
189
209
lib:: llvm:: SetUnnamedAddr ( llfn, true ) ;
190
- return llfn;
210
+
211
+ llfn
191
212
}
192
213
193
214
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
194
- pub fn decl_cdecl_fn ( llmod : ModuleRef , name : & str , ty : Type ) -> ValueRef {
195
- return decl_fn ( llmod, name, lib:: llvm:: CCallConv , ty) ;
215
+ pub fn decl_cdecl_fn ( llmod : ModuleRef ,
216
+ name : & str ,
217
+ ty : Type ,
218
+ output : ty:: t ) -> ValueRef {
219
+ decl_fn ( llmod, name, lib:: llvm:: CCallConv , ty, output)
196
220
}
197
221
198
222
// only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
199
- pub fn get_extern_fn ( externs : & mut ExternMap , llmod : ModuleRef , name : & str ,
200
- cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
223
+ pub fn get_extern_fn ( externs : & mut ExternMap , llmod : ModuleRef ,
224
+ name : & str , cc : lib:: llvm:: CallConv ,
225
+ ty : Type , output : ty:: t ) -> ValueRef {
201
226
match externs. find_equiv ( & name) {
202
227
Some ( n) => return * n,
203
- None => ( )
228
+ None => { }
204
229
}
205
- let f = decl_fn ( llmod, name, cc, ty) ;
230
+ let f = decl_fn ( llmod, name, cc, ty, output ) ;
206
231
externs. insert ( name. to_owned ( ) , f) ;
207
232
f
208
233
}
@@ -233,24 +258,7 @@ fn decl_rust_fn(ccx: &CrateContext,
233
258
output : ty:: t ,
234
259
name : & str ) -> ValueRef {
235
260
let llfty = type_of_rust_fn ( ccx, self_ty, inputs, output) ;
236
- let llfn = decl_cdecl_fn ( ccx. llmod , name, llfty) ;
237
-
238
- match ty:: get ( output) . sty {
239
- // functions returning bottom may unwind, but can never return normally
240
- ty:: ty_bot => {
241
- unsafe {
242
- llvm:: LLVMAddFunctionAttr ( llfn, lib:: llvm:: NoReturnAttribute as c_uint )
243
- }
244
- }
245
- // `~` pointer return values never alias because ownership is transferred
246
- ty:: ty_uniq( ..) |
247
- ty:: ty_vec( _, ty:: vstore_uniq) => {
248
- unsafe {
249
- llvm:: LLVMAddReturnAttribute ( llfn, lib:: llvm:: NoAliasAttribute as c_uint ) ;
250
- }
251
- }
252
- _ => ( )
253
- }
261
+ let llfn = decl_cdecl_fn ( ccx. llmod , name, llfty, output) ;
254
262
255
263
let uses_outptr = type_of:: return_uses_outptr ( ccx, output) ;
256
264
let offset = if uses_outptr { 2 } else { 1 } ;
@@ -259,8 +267,10 @@ fn decl_rust_fn(ccx: &CrateContext,
259
267
let llarg = unsafe { llvm:: LLVMGetParam ( llfn, ( offset + i) as c_uint ) } ;
260
268
match ty:: get ( arg_ty) . sty {
261
269
// `~` pointer parameters never alias because ownership is transferred
262
- ty:: ty_uniq( ..) |
263
- ty:: ty_vec( _, ty:: vstore_uniq) |
270
+ // FIXME #6750 ~Trait cannot be directly marked as
271
+ // noalias because the actual object pointer is nested.
272
+ ty:: ty_uniq( ..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
273
+ ty:: ty_vec( _, ty:: vstore_uniq) | ty:: ty_str( ty:: vstore_uniq) |
264
274
ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , ..} ) => {
265
275
unsafe {
266
276
llvm:: LLVMAddAttribute ( llarg, lib:: llvm:: NoAliasAttribute as c_uint ) ;
@@ -582,11 +592,8 @@ pub fn get_res_dtor(ccx: @CrateContext,
582
592
583
593
{
584
594
let mut externs = ccx. externs . borrow_mut ( ) ;
585
- get_extern_fn ( externs. get ( ) ,
586
- ccx. llmod ,
587
- name,
588
- lib:: llvm:: CCallConv ,
589
- llty)
595
+ get_extern_fn ( externs. get ( ) , ccx. llmod , name,
596
+ lib:: llvm:: CCallConv , llty, ty:: mk_nil ( ) )
590
597
}
591
598
}
592
599
}
@@ -917,7 +924,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
917
924
let cconv = c.unwrap_or(lib::llvm::CCallConv);
918
925
let llty = type_of_fn_from_ty(ccx, None, t);
919
926
let mut externs = ccx.externs.borrow_mut();
920
- get_extern_fn(externs.get(), ccx.llmod, name, cconv, llty)
927
+ get_extern_fn(externs.get(), ccx.llmod, name,
928
+ cconv, llty, fn_ty.sig.output)
921
929
}
922
930
}
923
931
}
@@ -2533,13 +2541,13 @@ pub fn register_fn_llvmty(ccx: @CrateContext,
2533
2541
sym : ~str ,
2534
2542
node_id : ast:: NodeId ,
2535
2543
cc : lib:: llvm:: CallConv ,
2536
- fn_ty : Type )
2537
- -> ValueRef {
2544
+ fn_ty : Type ,
2545
+ output : ty :: t ) -> ValueRef {
2538
2546
debug ! ( "register_fn_fuller creating fn for item {} with path {}" ,
2539
2547
node_id,
2540
2548
ast_map:: path_to_str( item_path( ccx, & node_id) , token:: get_ident_interner( ) ) ) ;
2541
2549
2542
- let llfn = decl_fn ( ccx. llmod , sym, cc, fn_ty) ;
2550
+ let llfn = decl_fn ( ccx. llmod , sym, cc, fn_ty, output ) ;
2543
2551
finish_register_fn ( ccx, sp, sym, node_id, llfn) ;
2544
2552
llfn
2545
2553
}
@@ -2571,7 +2579,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
2571
2579
let llfty = Type :: func ( [ ccx. int_type , Type :: i8 ( ) . ptr_to ( ) . ptr_to ( ) ] ,
2572
2580
& ccx. int_type ) ;
2573
2581
2574
- let llfn = decl_cdecl_fn ( ccx. llmod , "main" , llfty) ;
2582
+ let llfn = decl_cdecl_fn ( ccx. llmod , "main" , llfty, ty :: mk_nil ( ) ) ;
2575
2583
let llbb = "top" . with_c_str ( |buf| {
2576
2584
unsafe {
2577
2585
llvm:: LLVMAppendBasicBlockInContext ( ccx. llcx , llfn, buf)
@@ -2975,7 +2983,8 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef {
2975
2983
macro_rules! ifn (
2976
2984
( $intrinsics: ident, $name: expr, $args: expr, $ret: expr) => ( {
2977
2985
let name = $name;
2978
- let f = decl_cdecl_fn( llmod, name, Type :: func( $args, & $ret) ) ;
2986
+ // HACK(eddyb) dummy output type, shouln't affect anything.
2987
+ let f = decl_cdecl_fn( llmod, name, Type :: func( $args, & $ret) , ty:: mk_nil( ) ) ;
2979
2988
$intrinsics. insert( name, f) ;
2980
2989
} )
2981
2990
)
0 commit comments