llvm.org GIT mirror llvm / ab78ac1
tsan: handle vptr loads specially This is required to determine ctor/dtor vs virtual call races. http://llvm-reviews.chandlerc.com/D566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177717 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitry Vyukov 6 years ago
2 changed file(s) with 23 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
6262 "Number of reads ignored due to following writes");
6363 STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
6464 STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
65 STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
6566 STATISTIC(NumOmittedReadsFromConstantGlobals,
6667 "Number of reads from constant globals");
6768 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
107108 Function *TsanAtomicThreadFence;
108109 Function *TsanAtomicSignalFence;
109110 Function *TsanVptrUpdate;
111 Function *TsanVptrLoad;
110112 };
111113 } // namespace
112114
195197 TsanVptrUpdate = checkInterfaceFunction(M.getOrInsertFunction(
196198 "__tsan_vptr_update", IRB.getVoidTy(), IRB.getInt8PtrTy(),
197199 IRB.getInt8PtrTy(), NULL));
200 TsanVptrLoad = checkInterfaceFunction(M.getOrInsertFunction(
201 "__tsan_vptr_read", IRB.getVoidTy(), IRB.getInt8PtrTy(), NULL));
198202 TsanAtomicThreadFence = checkInterfaceFunction(M.getOrInsertFunction(
199203 "__tsan_atomic_thread_fence", IRB.getVoidTy(), OrdTy, NULL));
200204 TsanAtomicSignalFence = checkInterfaceFunction(M.getOrInsertFunction(
383387 IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
384388 IRB.CreatePointerCast(StoredValue, IRB.getInt8PtrTy()));
385389 NumInstrumentedVtableWrites++;
390 return true;
391 }
392 if (!IsWrite && isVtableAccess(I)) {
393 IRB.CreateCall(TsanVptrLoad,
394 IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
395 NumInstrumentedVtableReads++;
386396 return true;
387397 }
388398 Value *OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
0 ; RUN: opt < %s -tsan -S | FileCheck %s
1 ; Check that vptr reads are treated in a special way.
2 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-S128"
3
4 define i8 @Foo(i8* %a) nounwind uwtable {
5 entry:
6 ; CHECK: call void @__tsan_vptr_read
7 %0 = load i8* %a, align 8, !tbaa !0
8 ret i8 %0
9 }
10 !0 = metadata !{metadata !"vtable pointer", metadata !1}
11 !1 = metadata !{metadata !"Simple C/C++ TBAA", null}
12