Skip to content

Commit 171cca4

Browse files
committed
PerformanceDiagnostics: print an error in embedded swift if a value type deinit cannot be devirtualized
Not de-virtualized value type deinits can require metatype in case the deinit needs to be called via the value witness table. Usually this does not happen because deinits are mandatory de-virtualized. But it can show up if e.g. wrong build options are used. rdar://122651706
1 parent 3ecbfcf commit 171cca4

File tree

3 files changed

+13
-0
lines changed

3 files changed

+13
-0
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,8 @@ ERROR(perf_diag_existential_type,none,
365365
"cannot use a value of protocol type %0 in @_noExistential function", (Type))
366366
ERROR(perf_diag_existential,none,
367367
"cannot use a value of protocol type in @_noExistential function", ())
368+
ERROR(embedded_swift_value_deinit,none,
369+
"cannot de-virtualize deinit of type %0", (Type))
368370
ERROR(embedded_swift_metatype_type,none,
369371
"cannot use metatype of type %0 in embedded Swift", (Type))
370372
ERROR(embedded_swift_metatype,none,

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,12 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
870870
impactType = inst->getOperand(0)->getType();
871871
if (impactType.isBlockPointerCompatible())
872872
return RuntimeEffect::ObjectiveC | RuntimeEffect::Releasing;
873+
if (impactType.isMoveOnly() &&
874+
!isa<DropDeinitInst>(lookThroughOwnershipInsts(inst->getOperand(0)))) {
875+
// Not de-virtualized value type deinits can require metatype in case the
876+
// deinit needs to be called via the value witness table.
877+
return RuntimeEffect::MetaData | RuntimeEffect::Releasing;
878+
}
873879
return ifNonTrivial(inst->getOperand(0)->getType(),
874880
RuntimeEffect::Releasing);
875881

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,11 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
514514
}
515515

516516
if (impact & RuntimeEffect::MetaData) {
517+
if (isa<ReleaseValueInst>(inst)) {
518+
// Move-only value types for which the deinit is not de-virtualized.
519+
diagnose(loc, diag::embedded_swift_value_deinit, impactType.getASTType());
520+
return true;
521+
}
517522
if (!allowedMetadataUseInEmbeddedSwift(inst)) {
518523
PrettyStackTracePerformanceDiagnostics stackTrace("metatype", inst);
519524
if (impactType) {

0 commit comments

Comments
 (0)