@@ -5694,12 +5694,23 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
5694
5694
auto dst = alloc_ty( bcx, e_ty) ;
5695
5695
val = dst. val;
5696
5696
bcx = move_val_if_temp( dst. bcx, INIT , val, lv, e_ty) . bcx;
5697
- } else {
5698
- if ( lv. is_mem) { val = load_if_immediate( bcx, val, e_ty) ; }
5699
- // FIXME for non-is-mem lvals, we should be able to just drop the
5700
- // cleanup. However, this currently leads to a memory-corrupting
5701
- // stage2/rustc . Find out why.
5697
+ } else if ( lv. is_mem) {
5698
+ val = load_if_immediate( bcx, val, e_ty) ;
5702
5699
bcx = copy_ty( bcx, val, e_ty) . bcx;
5700
+ } else {
5701
+ // Eliding take/drop for appending of external vectors currently
5702
+ // corrupts memory. I can't figure out why, and external vectors
5703
+ // are on the way out anyway, so this simply turns off the
5704
+ // optimization for that case.
5705
+ auto is_ext_vec_plus = alt ( e. node) {
5706
+ case ( ast:: expr_binary( _, _, _) ) {
5707
+ ty:: type_is_sequence( ccx. tcx, e_ty) &&
5708
+ !ty:: sequence_is_interior( ccx. tcx, e_ty)
5709
+ }
5710
+ case ( _) { false }
5711
+ } ;
5712
+ if ( is_ext_vec_plus) { bcx = copy_ty( bcx, val, e_ty) . bcx; }
5713
+ else { revoke_clean( bcx, val) ; }
5703
5714
}
5704
5715
} else if ( type_is_immediate( ccx, e_ty) && !lv. is_mem) {
5705
5716
val = do_spill( bcx, val) ;
@@ -6368,11 +6379,8 @@ fn with_out_method(fn(&out_method) -> result work, @block_ctxt cx,
6368
6379
auto reg_val = load_if_immediate( cx, target, t) ;
6369
6380
ret drop_ty( cx, reg_val, t) ;
6370
6381
}
6371
- auto cleanup = bind drop_hoisted_ty( _, res_alloca. val, tp) ;
6372
- find_scope_cx( cx) . cleanups += ~[ clean_temp( res_alloca. val, cleanup) ] ;
6373
6382
auto done = work( save_in( res_alloca. val) ) ;
6374
6383
auto loaded = load_if_immediate( done. bcx, res_alloca. val, tp) ;
6375
- revoke_clean( cx, res_alloca. val) ;
6376
6384
add_clean_temp( cx, loaded, tp) ;
6377
6385
ret rslt( done. bcx, loaded) ; ;
6378
6386
}
0 commit comments