Emit unenforced access markers in SILGen for accesses to local temporaries.

These accesses can't be recognized as obviously local temporaries in the
verification pass, so the only way to exhaustively verify exclusivity is by
added unenforced markers.

SILGen currently only emits unenforced markers under -verify-exlcusivity. Once
opaque values is the only supported SILGen mode, then we should turn the markers
on by default (SILGen should not have different modes of operation).
This commit is contained in:
Andrew Trick
2017-12-11 19:44:36 -08:00
parent 34a968c334
commit 00b5a9db79
6 changed files with 232 additions and 21 deletions

View File

@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "Initialization.h"
#include "LValue.h"
#include "RValue.h"
#include "SILGen.h"
#include "SILGenDynamicCast.h"
@@ -192,15 +193,27 @@ void SingleBufferInitialization::
copyOrInitValueIntoSingleBuffer(SILGenFunction &SGF, SILLocation loc,
ManagedValue value, bool isInit,
SILValue destAddr) {
// Emit an unchecked access around initialization of the local buffer to
// silence access marker verification.
//
// FIXME: This is not a good place for FormalEvaluationScope +
// UnenforcedFormalAccess. However, there's no way to identify the buffer
// initialization sequence after SILGen, and no easy way to wrap the
// Initialization in an access during top-level expression evaluation.
FormalEvaluationScope scope(SGF);
if (!isInit) {
assert(value.getValue() != destAddr && "copying in place?!");
value.copyInto(SGF, destAddr, loc);
SILValue accessAddr =
UnenforcedFormalAccess::enter(SGF, loc, destAddr, SILAccessKind::Modify);
value.copyInto(SGF, accessAddr, loc);
return;
}
// If we didn't evaluate into the initialization buffer, do so now.
if (value.getValue() != destAddr) {
value.forwardInto(SGF, loc, destAddr);
SILValue accessAddr =
UnenforcedFormalAccess::enter(SGF, loc, destAddr, SILAccessKind::Modify);
value.forwardInto(SGF, loc, accessAddr);
} else {
// If we did evaluate into the initialization buffer, disable the
// cleanup.
@@ -828,10 +841,14 @@ void EnumElementPatternInitialization::emitEnumMatch(
SILValue boxedValue = SGF.B.createProjectBox(loc, mv.getValue(), 0);
auto &boxedTL = SGF.getTypeLowering(boxedValue->getType());
// SEMANTIC ARC TODO: Revisit this when the verifier is enabled.
if (boxedTL.isLoadable() || !SGF.silConv.useLoweredAddresses())
boxedValue = boxedTL.emitLoad(SGF.B, loc, boxedValue,
if (boxedTL.isLoadable() || !SGF.silConv.useLoweredAddresses()) {
UnenforcedAccess access;
SILValue accessAddress =
access.beginAccess(SGF, loc, boxedValue, SILAccessKind::Read);
boxedValue = boxedTL.emitLoad(SGF.B, loc, accessAddress,
LoadOwnershipQualifier::Take);
access.endAccess(SGF);
}
// We must treat the boxed value as +0 since it may be shared. Copy it
// if nontrivial.
//