SILGen: Reapply 'Add experimental TSan instrumentation for inout accesses.'

(This re-applies #7736 with an update to the
tsan-inout.swift execution test to handle configurations where
TSan's ignore_interceptors_accesses is enabled by default.)

Add SILGen instrumentation to treat inout accesses as Thread Sanitizer writes.
The goal is to catch races on inout accesses even when there is a not an
llvm-level read/write to a particular address. Ultimately
this will enable TSan to, for example, report racy writes to distinct
stored properties of a common struct as a data race.

This instrumentation is off by default. It can be enabled with the
'enable-experimental-tsan-inout-instrumentation' frontend flag.

The high-level approach is to add a SIL-level builtin that represents a call
to a TSan routine in compiler-rt. Then, when emitting an address for an LValue
as part of an inout expression, we call this builtin for each path component
that represents an LValue. I've added an 'isRValue()' method to PathComponent
that tracks whether a component represents an RValue or an LValue. Right the
only PathComponent that sometimes returns 'true' is ValueComponent().

For now, we're instrumenting only InoutExprs, but in the future it probably
makes sense to instrument all LValue accesses. In this patch I've
added a 'TSanKind' parameter to SILGenFunction::emitAddressOfLValue() and
its helpers to limit instrumentation to inout accesses. I envision that this
parameter will eventually go away.
This commit is contained in:
Devin Coughlin
2017-03-18 17:40:42 -07:00
parent 39473258a4
commit fdd9ea6c7d
11 changed files with 524 additions and 18 deletions

View File

@@ -847,6 +847,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.DisableAvailabilityChecking |=
Args.hasArg(OPT_disable_availability_checking);
Opts.EnableTSANInoutInstrumentation |=
Args.hasArg(OPT_enable_experimental_tsan_inout_instrumentation);
if (FrontendOpts.InputKind == InputFileKind::IFK_SIL)
Opts.DisableAvailabilityChecking = true;