@@ -3653,18 +3653,36 @@ void Verifier::visitCallBase(CallBase &Call) {
36533653 // well.
36543654 for (unsigned i = 0 , e = FTy->getNumParams (); i != e; ++i) {
36553655 if (Call.paramHasAttr (i, Attribute::SwiftError)) {
3656- Value *SwiftErrorArg = Call.getArgOperand (i);
3657- if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets ())) {
3658- Check (AI->isSwiftError (),
3659- " swifterror argument for call has mismatched alloca" , AI, Call);
3660- continue ;
3656+ SetVector<const Value *> Args;
3657+ Args.insert (Call.getArgOperand (i));
3658+ bool DidChange;
3659+ do {
3660+ DidChange = false ;
3661+ // Inherit the incoming values of phi instructions to capture all
3662+ // values.
3663+ for (const Value *Arg : Args)
3664+ if (auto *PhiI = dyn_cast<PHINode>(Arg))
3665+ for (const auto &Op : PhiI->incoming_values ())
3666+ DidChange |= Args.insert (Op.get ());
3667+ } while (DidChange);
3668+
3669+ for (const Value *SwiftErrorArg : Args) {
3670+ if (isa<PHINode>(SwiftErrorArg))
3671+ continue ;
3672+ if (auto AI =
3673+ dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets ())) {
3674+ Check (AI->isSwiftError (),
3675+ " swifterror argument for call has mismatched alloca" , AI, Call);
3676+ continue ;
3677+ }
3678+ auto ArgI = dyn_cast<Argument>(SwiftErrorArg);
3679+ Check (ArgI,
3680+ " swifterror argument should come from an alloca or parameter" ,
3681+ SwiftErrorArg, Call);
3682+ Check (ArgI->hasSwiftErrorAttr (),
3683+ " swifterror argument for call has mismatched parameter" , ArgI,
3684+ Call);
36613685 }
3662- auto ArgI = dyn_cast<Argument>(SwiftErrorArg);
3663- Check (ArgI, " swifterror argument should come from an alloca or parameter" ,
3664- SwiftErrorArg, Call);
3665- Check (ArgI->hasSwiftErrorAttr (),
3666- " swifterror argument for call has mismatched parameter" , ArgI,
3667- Call);
36683686 }
36693687
36703688 if (Attrs.hasParamAttr (i, Attribute::ImmArg)) {
@@ -4356,11 +4374,23 @@ void Verifier::verifySwiftErrorCall(CallBase &Call,
43564374}
43574375
43584376void Verifier::verifySwiftErrorValue (const Value *SwiftErrorVal) {
4377+ SetVector<const User *> Users (SwiftErrorVal->users ().begin (),
4378+ SwiftErrorVal->users ().end ());
4379+ bool DidChange;
4380+ do {
4381+ DidChange = false ;
4382+ // Inherit the users of phi instructions to capture all users.
4383+ for (const User *U : Users)
4384+ if (auto PhiI = dyn_cast<PHINode>(U))
4385+ for (const User *U : PhiI->users ())
4386+ DidChange |= Users.insert (U);
4387+ } while (DidChange);
4388+
43594389 // Check that swifterror value is only used by loads, stores, or as
43604390 // a swifterror argument.
4361- for (const User *U : SwiftErrorVal-> users () ) {
4391+ for (const User *U : Users ) {
43624392 Check (isa<LoadInst>(U) || isa<StoreInst>(U) || isa<CallInst>(U) ||
4363- isa<InvokeInst>(U),
4393+ isa<InvokeInst>(U) || isa<PHINode>(U) ,
43644394 " swifterror value can only be loaded and stored from, or "
43654395 " as a swifterror argument!" ,
43664396 SwiftErrorVal, U);
0 commit comments