@@ -3180,14 +3180,21 @@ fn copy_val(&@block_ctxt cx, copy_action action, ValueRef dst, ValueRef src,
3180
3180
ret rslt( bcx, bcx. build. Store ( src, dst) ) ;
3181
3181
} else if ( ty:: type_is_structural( ccx. tcx, t) ||
3182
3182
ty:: type_has_dynamic_size( ccx. tcx, t) ) {
3183
- auto bcx;
3183
+ // Check for self-assignment.
3184
+ auto do_copy_cx = new_sub_block_ctxt( cx, "do_copy") ;
3185
+ auto next_cx = new_sub_block_ctxt( cx, "next") ;
3186
+ auto self_assigning = cx. build. ICmp ( lib:: llvm:: LLVMIntNE ,
3187
+ cx. build. PointerCast ( dst, val_ty( src) ) , src) ;
3188
+ cx. build. CondBr ( self_assigning, do_copy_cx. llbb, next_cx. llbb) ;
3189
+
3184
3190
if ( action == DROP_EXISTING ) {
3185
- bcx = drop_ty( cx, dst, t) . bcx;
3186
- } else {
3187
- bcx = cx;
3191
+ do_copy_cx = drop_ty( do_copy_cx, dst, t) . bcx;
3188
3192
}
3189
- bcx = memmove_ty( bcx, dst, src, t) . bcx;
3190
- ret copy_ty( bcx, dst, t) ;
3193
+ do_copy_cx = memmove_ty( do_copy_cx, dst, src, t) . bcx;
3194
+ do_copy_cx = copy_ty( do_copy_cx, dst, t) . bcx;
3195
+ do_copy_cx. build. Br ( next_cx. llbb) ;
3196
+
3197
+ ret rslt( next_cx, C_nil ( ) ) ;
3191
3198
}
3192
3199
ccx. sess. bug( "unexpected type in trans:: copy_val: " +
3193
3200
ty_to_str( ccx. tcx, t) ) ;
0 commit comments