Call slot optimization may introduce writes to the destination object that occur earlier than in the original function. We currently already check that that the destination is dereferenceable and aligned, but we do not make sure that it is writable. As such, we might introduce a write to read-only memory, or introduce a data race. Fix this by checking that the object is writable. For arguments, this is indicated by the new writable attribute. Tests using sret/dereferenceable are updated to use it.
26 lines
1.1 KiB
LLVM
26 lines
1.1 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S < %s -passes=memcpyopt -verify-memoryssa | FileCheck %s
|
|
; <rdar://problem/8536696>
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
target triple = "x86_64-apple-darwin10.0.0"
|
|
|
|
%"class.std::auto_ptr" = type { ptr }
|
|
|
|
define void @_Z3foov(ptr noalias nocapture writable sret(%"class.std::auto_ptr") %agg.result) ssp {
|
|
; CHECK-LABEL: @_Z3foov(
|
|
; CHECK-NEXT: _ZNSt8auto_ptrIiED1Ev.exit:
|
|
; CHECK-NEXT: [[TEMP_LVALUE:%.*]] = alloca %"class.std::auto_ptr", align 8
|
|
; CHECK-NEXT: call void @_Z3barv(ptr sret(%"class.std::auto_ptr") [[AGG_RESULT:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
_ZNSt8auto_ptrIiED1Ev.exit:
|
|
%temp.lvalue = alloca %"class.std::auto_ptr", align 8
|
|
call void @_Z3barv(ptr sret(%"class.std::auto_ptr") %temp.lvalue)
|
|
%tmp2.i.i = load ptr, ptr %temp.lvalue, align 8
|
|
store ptr %tmp2.i.i, ptr %agg.result, align 8
|
|
ret void
|
|
}
|
|
|
|
declare void @_Z3barv(ptr nocapture sret(%"class.std::auto_ptr")) nounwind
|