Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/AST/DeclAttr.def
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
155)

SIMPLE_DECL_ATTR(_manualOwnership, ManualOwnership,
SIMPLE_DECL_ATTR(_noManualOwnership, NoManualOwnership,
OnAbstractFunction | OnSubscript,
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
156)
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticGroups.def
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ GROUP(ConformanceIsolation, "conformance-isolation")
GROUP(ForeignReferenceType, "foreign-reference-type")
GROUP(DeprecatedDeclaration, "deprecated-declaration")
GROUP(DynamicCallable, "dynamic-callable-requirements")
GROUP(DynamicExclusivity, "dynamic-exclusivity")
GROUP(EmbeddedRestrictions, "embedded-restrictions")
GROUP(ErrorInFutureSwiftVersion, "error-in-future-swift-version")
GROUP(ExclusivityViolation, "exclusivity-violation")
Expand All @@ -73,6 +74,7 @@ GROUP(ProtocolTypeNonConformance, "protocol-type-non-conformance")
GROUP(RegionIsolation, "region-isolation")
GROUP(ResultBuilderMethods, "result-builder-methods")
GROUP(ReturnTypeImplicitCopy, "return-type-implicit-copy")
GROUP(SemanticCopies, "semantic-copies")
GROUP(SendableClosureCaptures, "sendable-closure-captures")
GROUP(SendableMetatypes, "sendable-metatypes")
GROUP(SendingClosureRisksDataRace, "sending-closure-risks-data-race")
Expand Down
17 changes: 12 additions & 5 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -433,15 +433,22 @@ ERROR(wrong_linkage_for_serialized_function,none,
"function has wrong linkage to be called from %0", (StringRef))
NOTE(performance_called_from,none,
"called from here", ())
ERROR(manualownership_copy,none,
"explicit 'copy' required here; please report this vague diagnostic as a bug", ())
ERROR(manualownership_copy_happened,none,

// ManualOwnership diagnostics
GROUPED_WARNING(manualownership_copy,SemanticCopies,DefaultIgnore,
"implicit 'copy' happens here; please report this vague diagnostic as a bug", ())
GROUPED_WARNING(manualownership_copy_happened,SemanticCopies,DefaultIgnore,
"accessing %0 may produce a copy; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
ERROR(manualownership_copy_demanded,none,
GROUPED_WARNING(manualownership_copy_demanded,SemanticCopies,DefaultIgnore,
"independent copy of %0 is required here; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
ERROR(manualownership_copy_captured,none,
GROUPED_WARNING(manualownership_copy_captured,SemanticCopies,DefaultIgnore,
"closure capture of '%0' requires independent copy of it; write [%0 = copy %0] in the closure's capture list to acknowledge", (StringRef))

GROUPED_WARNING(manualownership_exclusivity,DynamicExclusivity,DefaultIgnore,
"exclusive access here will be checked at runtime; please report this vague diagnostic as a bug", ())
GROUPED_WARNING(manualownership_exclusivity_named,DynamicExclusivity,DefaultIgnore,
"accessing %0 here may incur runtime exclusivity check%1", (Identifier, StringRef))

// 'transparent' diagnostics
ERROR(circular_transparent,none,
"inlining 'transparent' functions forms circular loop", ())
Expand Down
4 changes: 1 addition & 3 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,7 @@ ERROR(attr_static_exclusive_only_mutating,none,
ERROR(attr_static_exclusive_no_setters,none,
"variable of type %0 must not have a setter", (Type))

// @_manualOwnership
ERROR(attr_manual_ownership_experimental,none,
"'@_manualOwnership' requires '-enable-experimental-feature ManualOwnership'", ())
// ManualOwnership
ERROR(attr_manual_ownership_noimplicitcopy,none,
"'@_noImplicitCopy' cannot be used with ManualOwnership", ())

Expand Down
4 changes: 3 additions & 1 deletion include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,9 @@ EXPERIMENTAL_FEATURE(LifetimeDependence, true)
/// Enable the `@_staticExclusiveOnly` attribute.
EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)

/// Enable the `@_manualOwnership` attribute.
/// Enable the ManualOwnership diagnostic groups:
/// * -Wwarning SemanticCopies
/// * -Wwarning DynamicExclusivity
EXPERIMENTAL_FEATURE(ManualOwnership, false)

/// Enable the @extractConstantsFromMembers attribute.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5024,7 +5024,7 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
TRIVIAL_ATTR_PRINTER(NoLocks, no_locks)
TRIVIAL_ATTR_PRINTER(NoMetadata, no_metadata)
TRIVIAL_ATTR_PRINTER(NoObjCBridging, no_objc_bridging)
TRIVIAL_ATTR_PRINTER(ManualOwnership, manual_ownership)
TRIVIAL_ATTR_PRINTER(NoManualOwnership, no_manual_ownership)
TRIVIAL_ATTR_PRINTER(NoRuntime, no_runtime)
TRIVIAL_ATTR_PRINTER(NonEphemeral, non_ephemeral)
TRIVIAL_ATTR_PRINTER(NonEscapable, non_escapable)
Expand Down
2 changes: 1 addition & 1 deletion lib/ASTGen/Sources/ASTGen/DeclAttrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ extension ASTGenVisitor {
.LexicalLifetimes,
.LLDBDebuggerFunction,
.MainType,
.ManualOwnership,
.Marker,
.MoveOnly,
.NeverEmitIntoClient,
Expand All @@ -276,6 +275,7 @@ extension ASTGenVisitor {
.NoRuntime,
.NoImplicitCopy,
.NoLocks,
.NoManualOwnership,
.NoMetadata,
.NoObjCBridging,
.NonEphemeral,
Expand Down
4 changes: 3 additions & 1 deletion lib/SIL/IR/SILFunctionBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ void SILFunctionBuilder::addFunctionAttributes(
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
} else if (Attrs.hasAttribute<ManualOwnershipAttr>()) {
} else if (M.getASTContext().LangOpts.hasFeature(Feature::ManualOwnership) &&
constant && constant.hasDecl() && !constant.isImplicit() &&
!Attrs.hasAttribute<NoManualOwnershipAttr>()) {
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
}

Expand Down
18 changes: 9 additions & 9 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1368,15 +1368,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
//
// If ManualOwnership ends up subsuming those prior mechanisms for an
// explicit-copy mode, we can move this somewhere else, like postEmitFunction.
if (auto *ace = constant.getAbstractClosureExpr()) {
if (auto *dc = ace->getOutermostFunctionContext()) {
if (auto *decl = dc->getAsDecl()) {
if (decl->getAttrs().hasAttribute<ManualOwnershipAttr>()) {
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
}
}
}
}
//
// FIXME: maybe this should happen in SILFunctionBuilder::getOrCreateFunction
if (getASTContext().LangOpts.hasFeature(Feature::ManualOwnership))
if (auto *ace = constant.getAbstractClosureExpr())
if (auto *dc = ace->getOutermostFunctionContext())
if (auto *decl = dc->getAsDecl())
if (!decl->isImplicit() &&
!decl->getAttrs().hasAttribute<NoManualOwnershipAttr>())
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);

LLVM_DEBUG(llvm::dbgs() << "lowering ";
F->printName(llvm::dbgs());
Expand Down
43 changes: 43 additions & 0 deletions lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,49 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
return false;
}
}
if (impact & RuntimeEffect::ExclusivityChecking) {
switch (inst->getKind()) {
case SILInstructionKind::BeginUnpairedAccessInst:
case SILInstructionKind::EndUnpairedAccessInst:
// These instructions are quite unusual; they seem to only ever created
// explicitly by calling functions from the Builtin module, see:
// - emitBuiltinPerformInstantaneousReadAccess
// - emitBuiltinEndUnpairedAccess
break;
case SILInstructionKind::EndAccessInst:
break; // We'll already diagnose the begin access.
case SILInstructionKind::BeginAccessInst: {
auto bai = cast<BeginAccessInst>(inst);
auto info = VariableNameInferrer::inferNameAndRoot(bai->getSource());

if (!info) {
LLVM_DEBUG(llvm::dbgs() << "exclusivity (no name?): " << *inst);
diagnose(loc, diag::manualownership_exclusivity);
return false;
}
Identifier name = info->first;
SILValue root = info->second;
StringRef advice = "";

// Try to classify the root to give advice.
if (isa<GlobalAddrInst>(root)) {
advice = ", because it involves a global variable";
} else if (root->getType().isAnyClassReferenceType()) {
advice = ", because it's a member of a reference type";
}

LLVM_DEBUG(llvm::dbgs() << "exclusivity: " << *inst);
LLVM_DEBUG(llvm::dbgs() << "with root: " << root);

diagnose(loc, diag::manualownership_exclusivity_named, name, advice);
break;
}
default:
LLVM_DEBUG(llvm::dbgs() << "UNKNOWN EXCLUSIVITY INST: " << *inst);
diagnose(loc, diag::manualownership_exclusivity);
return false;
}
}
return false;
}

Expand Down
1 change: 1 addition & 0 deletions lib/SILOptimizer/Utils/VariableNameUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ SILValue VariableNameInferrer::findDebugInfoProvidingValueHelper(
isa<LoadBorrowInst>(searchValue) || isa<BeginAccessInst>(searchValue) ||
isa<MarkUnresolvedNonCopyableValueInst>(searchValue) ||
isa<ProjectBoxInst>(searchValue) || isa<CopyValueInst>(searchValue) ||
isa<ExplicitCopyValueInst>(searchValue) ||
isa<ConvertFunctionInst>(searchValue) ||
isa<MarkUninitializedInst>(searchValue) ||
isa<MarkDependenceInst>(searchValue) ||
Expand Down
9 changes: 1 addition & 8 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
IGNORED_ATTR(NoAllocation)
IGNORED_ATTR(NoRuntime)
IGNORED_ATTR(NoExistentials)
IGNORED_ATTR(NoManualOwnership)
IGNORED_ATTR(NoObjCBridging)
IGNORED_ATTR(EmitAssemblyVisionRemarks)
IGNORED_ATTR(ShowInInterface)
Expand Down Expand Up @@ -476,7 +477,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
void visitUnsafeNonEscapableResultAttr(UnsafeNonEscapableResultAttr *attr);

void visitStaticExclusiveOnlyAttr(StaticExclusiveOnlyAttr *attr);
void visitManualOwnershipAttr(ManualOwnershipAttr *attr);
void visitWeakLinkedAttr(WeakLinkedAttr *attr);
void visitSILGenNameAttr(SILGenNameAttr *attr);
void visitLifetimeAttr(LifetimeAttr *attr);
Expand Down Expand Up @@ -8408,13 +8408,6 @@ void AttributeChecker::visitStaticExclusiveOnlyAttr(
}
}

void AttributeChecker::visitManualOwnershipAttr(ManualOwnershipAttr *attr) {
if (Ctx.LangOpts.hasFeature(Feature::ManualOwnership))
return;

diagnoseAndRemoveAttr(attr, diag::attr_manual_ownership_experimental);
}

void AttributeChecker::visitWeakLinkedAttr(WeakLinkedAttr *attr) {
if (!Ctx.LangOpts.Target.isOSBinFormatCOFF())
return;
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckDeclOverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1620,8 +1620,8 @@ namespace {
UNINTERESTING_ATTR(NoAllocation)
UNINTERESTING_ATTR(NoRuntime)
UNINTERESTING_ATTR(NoExistentials)
UNINTERESTING_ATTR(NoManualOwnership)
UNINTERESTING_ATTR(NoObjCBridging)
UNINTERESTING_ATTR(ManualOwnership)
UNINTERESTING_ATTR(Inlinable)
UNINTERESTING_ATTR(Effects)
UNINTERESTING_ATTR(Expose)
Expand Down
Loading