@@ -341,32 +341,45 @@ FunctionSideEffectFlags *FunctionSideEffects::getEffectsOn(SILValue Addr) {
341341 return &GlobalEffects;
342342}
343343
344+ bool FunctionSideEffects::setParamEffects (SILFunction *F) {
345+ for (auto i :
346+ range (F->getLoweredFunctionType ()->getNumIndirectFormalResults ())) {
347+ ParamEffects[i].Writes = true ;
348+ }
349+ for (auto ¶mAndIdx :
350+ enumerate(F->getLoweredFunctionType ()->getParameters ())) {
351+ auto ¶m = paramAndIdx.value ();
352+ if (param.isIndirectMutating () || param.isConsumed ()) {
353+ return false ;
354+ }
355+ }
356+ return true ;
357+ }
358+
344359// Return true if the given function has defined effects that were successfully
345360// recorded in this FunctionSideEffects object.
346361bool FunctionSideEffects::setDefinedEffects (SILFunction *F) {
347362 if (F->hasSemanticsAttr (SEMANTICS_PROGRAMTERMINATION_POINT)) {
348363 Traps = true ;
349364 return true ;
350365 }
366+
351367 switch (F->getEffectsKind ()) {
352- case EffectsKind::ReleaseNone:
353- GlobalEffects.Reads = true ;
354- GlobalEffects.Writes = true ;
355- GlobalEffects.Releases = false ;
356- return true ;
357- case EffectsKind::ReadNone:
358- return true ;
359- case EffectsKind::ReadOnly:
360- // @_effects(readonly) is worthless if we have owned parameters, because
361- // the release inside the callee may call a deinit, which itself can do
362- // anything.
363- if (!F->hasOwnedParameters ()) {
364- GlobalEffects.Reads = true ;
365- return true ;
366- }
367- break ;
368- default :
369- break ;
368+ case EffectsKind::ReleaseNone: {
369+ GlobalEffects.Reads = true ;
370+ GlobalEffects.Writes = true ;
371+ GlobalEffects.Releases = false ;
372+ return setParamEffects (F);
373+ }
374+ case EffectsKind::ReadNone: {
375+ return setParamEffects (F);
376+ }
377+ case EffectsKind::ReadOnly: {
378+ GlobalEffects.Reads = true ;
379+ return setParamEffects (F);
380+ }
381+ default :
382+ break ;
370383 }
371384
372385 return false ;
@@ -523,6 +536,7 @@ void FunctionSideEffects::analyzeInstruction(SILInstruction *I) {
523536#include " swift/AST/ReferenceStorage.def"
524537 case SILInstructionKind::StrongRetainInst:
525538 case SILInstructionKind::RetainValueInst:
539+ case SILInstructionKind::CopyValueInst:
526540 getEffectsOn (I->getOperand (0 ))->Retains = true ;
527541 return ;
528542#define UNCHECKED_REF_STORAGE (Name, ...) \
@@ -532,6 +546,8 @@ void FunctionSideEffects::analyzeInstruction(SILInstruction *I) {
532546#include " swift/AST/ReferenceStorage.def"
533547 case SILInstructionKind::StrongReleaseInst:
534548 case SILInstructionKind::ReleaseValueInst:
549+ case SILInstructionKind::DestroyValueInst:
550+ case SILInstructionKind::DestroyAddrInst:
535551 getEffectsOn (I->getOperand (0 ))->Releases = true ;
536552 return ;
537553 case SILInstructionKind::UnconditionalCheckedCastInst:
0 commit comments