Skip to content

Commit 03d61ed

Browse files
authored
Merge pull request #85090 from kavon/manual-ownership/usability-fixes-6
ManualOwnership: provide ability to apply to entire compilation unit
2 parents b477708 + 2d881bd commit 03d61ed

19 files changed

+221
-146
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
815815
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
816816
155)
817817

818-
SIMPLE_DECL_ATTR(_manualOwnership, ManualOwnership,
818+
SIMPLE_DECL_ATTR(_noManualOwnership, NoManualOwnership,
819819
OnAbstractFunction | OnSubscript,
820820
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
821821
156)

include/swift/AST/DiagnosticGroups.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ GROUP(ConformanceIsolation, "conformance-isolation")
4949
GROUP(ForeignReferenceType, "foreign-reference-type")
5050
GROUP(DeprecatedDeclaration, "deprecated-declaration")
5151
GROUP(DynamicCallable, "dynamic-callable-requirements")
52+
GROUP(DynamicExclusivity, "dynamic-exclusivity")
5253
GROUP(EmbeddedRestrictions, "embedded-restrictions")
5354
GROUP(ErrorInFutureSwiftVersion, "error-in-future-swift-version")
5455
GROUP(ExclusivityViolation, "exclusivity-violation")
@@ -73,6 +74,7 @@ GROUP(ProtocolTypeNonConformance, "protocol-type-non-conformance")
7374
GROUP(RegionIsolation, "region-isolation")
7475
GROUP(ResultBuilderMethods, "result-builder-methods")
7576
GROUP(ReturnTypeImplicitCopy, "return-type-implicit-copy")
77+
GROUP(SemanticCopies, "semantic-copies")
7678
GROUP(SendableClosureCaptures, "sendable-closure-captures")
7779
GROUP(SendableMetatypes, "sendable-metatypes")
7880
GROUP(SendingClosureRisksDataRace, "sending-closure-risks-data-race")

include/swift/AST/DiagnosticsSIL.def

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -433,15 +433,22 @@ ERROR(wrong_linkage_for_serialized_function,none,
433433
"function has wrong linkage to be called from %0", (StringRef))
434434
NOTE(performance_called_from,none,
435435
"called from here", ())
436-
ERROR(manualownership_copy,none,
437-
"explicit 'copy' required here; please report this vague diagnostic as a bug", ())
438-
ERROR(manualownership_copy_happened,none,
436+
437+
// ManualOwnership diagnostics
438+
GROUPED_WARNING(manualownership_copy,SemanticCopies,DefaultIgnore,
439+
"implicit 'copy' happens here; please report this vague diagnostic as a bug", ())
440+
GROUPED_WARNING(manualownership_copy_happened,SemanticCopies,DefaultIgnore,
439441
"accessing %0 may produce a copy; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
440-
ERROR(manualownership_copy_demanded,none,
442+
GROUPED_WARNING(manualownership_copy_demanded,SemanticCopies,DefaultIgnore,
441443
"independent copy of %0 is required here; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
442-
ERROR(manualownership_copy_captured,none,
444+
GROUPED_WARNING(manualownership_copy_captured,SemanticCopies,DefaultIgnore,
443445
"closure capture of '%0' requires independent copy of it; write [%0 = copy %0] in the closure's capture list to acknowledge", (StringRef))
444446

447+
GROUPED_WARNING(manualownership_exclusivity,DynamicExclusivity,DefaultIgnore,
448+
"exclusive access here will be checked at runtime; please report this vague diagnostic as a bug", ())
449+
GROUPED_WARNING(manualownership_exclusivity_named,DynamicExclusivity,DefaultIgnore,
450+
"accessing %0 here may incur runtime exclusivity check%1", (Identifier, StringRef))
451+
445452
// 'transparent' diagnostics
446453
ERROR(circular_transparent,none,
447454
"inlining 'transparent' functions forms circular loop", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,9 +2145,7 @@ ERROR(attr_static_exclusive_only_mutating,none,
21452145
ERROR(attr_static_exclusive_no_setters,none,
21462146
"variable of type %0 must not have a setter", (Type))
21472147

2148-
// @_manualOwnership
2149-
ERROR(attr_manual_ownership_experimental,none,
2150-
"'@_manualOwnership' requires '-enable-experimental-feature ManualOwnership'", ())
2148+
// ManualOwnership
21512149
ERROR(attr_manual_ownership_noimplicitcopy,none,
21522150
"'@_noImplicitCopy' cannot be used with ManualOwnership", ())
21532151

include/swift/Basic/Features.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,9 @@ EXPERIMENTAL_FEATURE(LifetimeDependence, true)
449449
/// Enable the `@_staticExclusiveOnly` attribute.
450450
EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
451451

452-
/// Enable the `@_manualOwnership` attribute.
452+
/// Enable the ManualOwnership diagnostic groups:
453+
/// * -Wwarning SemanticCopies
454+
/// * -Wwarning DynamicExclusivity
453455
EXPERIMENTAL_FEATURE(ManualOwnership, false)
454456

455457
/// Enable the @extractConstantsFromMembers attribute.

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5024,7 +5024,7 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
50245024
TRIVIAL_ATTR_PRINTER(NoLocks, no_locks)
50255025
TRIVIAL_ATTR_PRINTER(NoMetadata, no_metadata)
50265026
TRIVIAL_ATTR_PRINTER(NoObjCBridging, no_objc_bridging)
5027-
TRIVIAL_ATTR_PRINTER(ManualOwnership, manual_ownership)
5027+
TRIVIAL_ATTR_PRINTER(NoManualOwnership, no_manual_ownership)
50285028
TRIVIAL_ATTR_PRINTER(NoRuntime, no_runtime)
50295029
TRIVIAL_ATTR_PRINTER(NonEphemeral, non_ephemeral)
50305030
TRIVIAL_ATTR_PRINTER(NonEscapable, non_escapable)

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ extension ASTGenVisitor {
265265
.LexicalLifetimes,
266266
.LLDBDebuggerFunction,
267267
.MainType,
268-
.ManualOwnership,
269268
.Marker,
270269
.MoveOnly,
271270
.NeverEmitIntoClient,
@@ -276,6 +275,7 @@ extension ASTGenVisitor {
276275
.NoRuntime,
277276
.NoImplicitCopy,
278277
.NoLocks,
278+
.NoManualOwnership,
279279
.NoMetadata,
280280
.NoObjCBridging,
281281
.NonEphemeral,

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ void SILFunctionBuilder::addFunctionAttributes(
208208
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
209209
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
210210
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
211-
} else if (Attrs.hasAttribute<ManualOwnershipAttr>()) {
211+
} else if (M.getASTContext().LangOpts.hasFeature(Feature::ManualOwnership) &&
212+
constant && constant.hasDecl() && !constant.isImplicit() &&
213+
!Attrs.hasAttribute<NoManualOwnershipAttr>()) {
212214
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
213215
}
214216

lib/SILGen/SILGen.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,15 +1368,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
13681368
//
13691369
// If ManualOwnership ends up subsuming those prior mechanisms for an
13701370
// explicit-copy mode, we can move this somewhere else, like postEmitFunction.
1371-
if (auto *ace = constant.getAbstractClosureExpr()) {
1372-
if (auto *dc = ace->getOutermostFunctionContext()) {
1373-
if (auto *decl = dc->getAsDecl()) {
1374-
if (decl->getAttrs().hasAttribute<ManualOwnershipAttr>()) {
1375-
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
1376-
}
1377-
}
1378-
}
1379-
}
1371+
//
1372+
// FIXME: maybe this should happen in SILFunctionBuilder::getOrCreateFunction
1373+
if (getASTContext().LangOpts.hasFeature(Feature::ManualOwnership))
1374+
if (auto *ace = constant.getAbstractClosureExpr())
1375+
if (auto *dc = ace->getOutermostFunctionContext())
1376+
if (auto *decl = dc->getAsDecl())
1377+
if (!decl->isImplicit() &&
1378+
!decl->getAttrs().hasAttribute<NoManualOwnershipAttr>())
1379+
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
13801380

13811381
LLVM_DEBUG(llvm::dbgs() << "lowering ";
13821382
F->printName(llvm::dbgs());

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,49 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
489489
return false;
490490
}
491491
}
492+
if (impact & RuntimeEffect::ExclusivityChecking) {
493+
switch (inst->getKind()) {
494+
case SILInstructionKind::BeginUnpairedAccessInst:
495+
case SILInstructionKind::EndUnpairedAccessInst:
496+
// These instructions are quite unusual; they seem to only ever created
497+
// explicitly by calling functions from the Builtin module, see:
498+
// - emitBuiltinPerformInstantaneousReadAccess
499+
// - emitBuiltinEndUnpairedAccess
500+
break;
501+
case SILInstructionKind::EndAccessInst:
502+
break; // We'll already diagnose the begin access.
503+
case SILInstructionKind::BeginAccessInst: {
504+
auto bai = cast<BeginAccessInst>(inst);
505+
auto info = VariableNameInferrer::inferNameAndRoot(bai->getSource());
506+
507+
if (!info) {
508+
LLVM_DEBUG(llvm::dbgs() << "exclusivity (no name?): " << *inst);
509+
diagnose(loc, diag::manualownership_exclusivity);
510+
return false;
511+
}
512+
Identifier name = info->first;
513+
SILValue root = info->second;
514+
StringRef advice = "";
515+
516+
// Try to classify the root to give advice.
517+
if (isa<GlobalAddrInst>(root)) {
518+
advice = ", because it involves a global variable";
519+
} else if (root->getType().isAnyClassReferenceType()) {
520+
advice = ", because it's a member of a reference type";
521+
}
522+
523+
LLVM_DEBUG(llvm::dbgs() << "exclusivity: " << *inst);
524+
LLVM_DEBUG(llvm::dbgs() << "with root: " << root);
525+
526+
diagnose(loc, diag::manualownership_exclusivity_named, name, advice);
527+
break;
528+
}
529+
default:
530+
LLVM_DEBUG(llvm::dbgs() << "UNKNOWN EXCLUSIVITY INST: " << *inst);
531+
diagnose(loc, diag::manualownership_exclusivity);
532+
return false;
533+
}
534+
}
492535
return false;
493536
}
494537

0 commit comments

Comments
 (0)