mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
adding the @_compilerInitialized attribute
This attribute is designed for let-bound variables whose initializing assignment is synthesized by the compiler. This assignment is expected to happen at some point before DefiniteInitialization has run, which is the pass that verifies whether the compiler truly initialized the variable. I generally expect that this will never be a user-facing feature, and that the synthesized assignment happens in SILGen.
This commit is contained in:
@@ -524,6 +524,10 @@ private:
|
||||
/// of this.
|
||||
bool InEnumSubElement = false;
|
||||
|
||||
/// If true, then encountered uses correspond to a VarDecl marked
|
||||
/// as \p @_compilerInitialized
|
||||
bool InCompilerInitializedField = false;
|
||||
|
||||
public:
|
||||
ElementUseCollector(const DIMemoryObjectInfo &TheMemory,
|
||||
DIElementUseInfo &UseInfo,
|
||||
@@ -665,6 +669,16 @@ static SILValue getAccessedPointer(SILValue Pointer) {
|
||||
return Pointer;
|
||||
}
|
||||
|
||||
static DIUseKind verifyCompilerInitialized(SILValue pointer,
|
||||
SILInstruction *write,
|
||||
DIUseKind origKind) {
|
||||
// if the write is _not_ auto-generated, it's a bad store.
|
||||
if (!write->getLoc().isAutoGenerated())
|
||||
return DIUseKind::BadExplicitStore;
|
||||
|
||||
return origKind;
|
||||
}
|
||||
|
||||
void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
|
||||
assert(Pointer->getType().isAddress() &&
|
||||
"Walked through the pointer to the value?");
|
||||
@@ -733,6 +747,11 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
|
||||
else
|
||||
Kind = DIUseKind::Initialization;
|
||||
|
||||
// If it's a non-synthesized write to a @_compilerInitialized field,
|
||||
// indicate that in the Kind.
|
||||
if (LLVM_UNLIKELY(InCompilerInitializedField))
|
||||
Kind = verifyCompilerInitialized(Pointer, User, Kind);
|
||||
|
||||
addElementUses(BaseEltNo, PointeeType, User, Kind);
|
||||
continue;
|
||||
}
|
||||
@@ -1403,9 +1422,15 @@ void ElementUseCollector::collectClassSelfUses(
|
||||
if (EltNumbering.count(REAI->getField()) != 0) {
|
||||
assert(EltNumbering.count(REAI->getField()) &&
|
||||
"ref_element_addr not a local field?");
|
||||
|
||||
// Remember whether the field is marked '@_compilerInitialized'
|
||||
const bool hasCompInit =
|
||||
REAI->getField()->getAttrs().hasAttribute<CompilerInitializedAttr>();
|
||||
llvm::SaveAndRestore<bool> X1(InCompilerInitializedField, hasCompInit);
|
||||
|
||||
// Recursively collect uses of the fields. Note that fields of the class
|
||||
// could be tuples, so they may be tracked as independent elements.
|
||||
llvm::SaveAndRestore<bool> X(IsSelfOfNonDelegatingInitializer, false);
|
||||
llvm::SaveAndRestore<bool> X2(IsSelfOfNonDelegatingInitializer, false);
|
||||
collectUses(REAI, EltNumbering[REAI->getField()]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user