@@ -42,10 +42,21 @@ using namespace swift;
42
42
// prevent release builds from triggering spurious unused variable warnings.
43
43
#ifndef NDEBUG
44
44
45
- llvm::cl::opt<bool > PrintMessageInsteadOfAssert (
46
- " sil-ownership-verifier-do-not-assert" ,
47
- llvm::cl::desc (" Print out message instead of asserting. "
48
- " Meant for debugging" ));
45
+ // This is an option to put the SILOwnershipVerifier in testing mode. This
46
+ // causes the following:
47
+ //
48
+ // 1. Instead of printing an error message and aborting, the verifier will print
49
+ // the message and continue. This allows for FileCheck testing of the verifier.
50
+ //
51
+ // 2. SILInstruction::verifyOperandOwnership() is disabled. This is used for
52
+ // verification in SILBuilder. This causes errors to be printed twice, once when
53
+ // we build the IR and a second time when we perform a full verification of the
54
+ // IR. For testing purposes, we just want the later.
55
+ llvm::cl::opt<bool > IsSILOwnershipVerifierTestingEnabled (
56
+ " sil-ownership-verifier-enable-testing" ,
57
+ llvm::cl::desc (" Put the sil ownership verifier in testing mode. See "
58
+ " comment in SILOwnershipVerifier.cpp above option for more "
59
+ " information." ));
49
60
50
61
// ===----------------------------------------------------------------------===//
51
62
// Utility
@@ -116,7 +127,7 @@ class OwnershipCompatibilityUseChecker
116
127
<< " Have operand with incompatible ownership?!\n "
117
128
<< " Value: " << *getValue () << " User: " << *User
118
129
<< " Conv: " << getOwnershipKind () << " \n\n " ;
119
- if (PrintMessageInsteadOfAssert )
130
+ if (IsSILOwnershipVerifierTestingEnabled )
120
131
return false ;
121
132
llvm_unreachable (" triggering standard assertion failure routine" );
122
133
}
@@ -760,7 +771,7 @@ static bool checkFunctionArgWithoutLifetimeEndingUses(SILFunctionArgument *Arg,
760
771
<< " Owned function parameter without life "
761
772
" ending uses!\n "
762
773
<< " Value: " << *Arg << ' \n ' ;
763
- if (PrintMessageInsteadOfAssert )
774
+ if (IsSILOwnershipVerifierTestingEnabled )
764
775
return true ;
765
776
llvm_unreachable (" triggering standard assertion failure routine" );
766
777
}
@@ -779,7 +790,7 @@ bool SILValueOwnershipChecker::checkValueWithoutLifetimeEndingUses() {
779
790
" guaranteed function args must have at least one "
780
791
" lifetime ending use?!\n "
781
792
<< " Value: " << *Value << ' \n ' ;
782
- if (PrintMessageInsteadOfAssert )
793
+ if (IsSILOwnershipVerifierTestingEnabled )
783
794
return true ;
784
795
llvm_unreachable (" triggering standard assertion failure routine" );
785
796
}
@@ -800,7 +811,7 @@ static bool isGuaranteedFunctionArgWithLifetimeEndingUses(
800
811
llvm::errs () << " Lifetime Ending User: " << *U;
801
812
}
802
813
llvm::errs () << ' \n ' ;
803
- if (PrintMessageInsteadOfAssert )
814
+ if (IsSILOwnershipVerifierTestingEnabled )
804
815
return false ;
805
816
llvm_unreachable (" triggering standard assertion failure routine" );
806
817
}
@@ -870,14 +881,14 @@ bool SILValueOwnershipChecker::checkUses() {
870
881
// If the block does over consume, we either assert or return false. We only
871
882
// return false when debugging.
872
883
if (doesBlockDoubleConsume (UserBlock, User, true )) {
873
- if (PrintMessageInsteadOfAssert )
884
+ if (IsSILOwnershipVerifierTestingEnabled )
874
885
return false ;
875
886
llvm_unreachable (" triggering standard assertion failure routine" );
876
887
}
877
888
878
889
// Then check if the given block has a use after free.
879
890
if (doesBlockContainUseAfterFree (User, UserBlock)) {
880
- if (PrintMessageInsteadOfAssert )
891
+ if (IsSILOwnershipVerifierTestingEnabled )
881
892
return false ;
882
893
llvm_unreachable (" triggering standard assertion failure routine" );
883
894
}
@@ -907,7 +918,7 @@ bool SILValueOwnershipChecker::checkUses() {
907
918
// Make sure that the predecessor is not in our
908
919
// BlocksWithLifetimeEndingUses list.
909
920
if (doesBlockDoubleConsume (PredBlock, User)) {
910
- if (PrintMessageInsteadOfAssert )
921
+ if (IsSILOwnershipVerifierTestingEnabled )
911
922
return false ;
912
923
llvm_unreachable (" triggering standard assertion failure routine" );
913
924
}
@@ -965,7 +976,7 @@ void SILValueOwnershipChecker::checkDataflow() {
965
976
// 2. We add the predecessor to the worklist if we have not visited it yet.
966
977
for (auto *PredBlock : BB->getPredecessorBlocks ()) {
967
978
if (doesBlockDoubleConsume (PredBlock)) {
968
- if (PrintMessageInsteadOfAssert )
979
+ if (IsSILOwnershipVerifierTestingEnabled )
969
980
return ;
970
981
llvm_unreachable (" triggering standard assertion failure routine" );
971
982
}
@@ -989,7 +1000,7 @@ void SILValueOwnershipChecker::checkDataflow() {
989
1000
llvm::errs () << " bb" << BB->getDebugID ();
990
1001
}
991
1002
llvm::errs () << ' \n ' ;
992
- if (PrintMessageInsteadOfAssert )
1003
+ if (IsSILOwnershipVerifierTestingEnabled )
993
1004
return ;
994
1005
llvm_unreachable (" triggering standard assertion failure routine" );
995
1006
}
@@ -1006,7 +1017,7 @@ void SILValueOwnershipChecker::checkDataflow() {
1006
1017
llvm::errs () << " User:" << *Pair.second << " Block: bb"
1007
1018
<< Pair.first ->getDebugID () << " \n\n " ;
1008
1019
}
1009
- if (PrintMessageInsteadOfAssert )
1020
+ if (IsSILOwnershipVerifierTestingEnabled )
1010
1021
return ;
1011
1022
llvm_unreachable (" triggering standard assertion failure routine" );
1012
1023
}
@@ -1023,6 +1034,10 @@ void SILInstruction::verifyOperandOwnership() const {
1023
1034
// If SILOwnership is not enabled, do not perform verification.
1024
1035
if (!getModule ().getOptions ().EnableSILOwnership )
1025
1036
return ;
1037
+ // If we are testing the verifier, bail so we only print errors once when
1038
+ // performing a full verification, instead of additionally in the SILBuilder.
1039
+ if (IsSILOwnershipVerifierTestingEnabled)
1040
+ return ;
1026
1041
auto *Self = const_cast <SILInstruction *>(this );
1027
1042
for (const Operand &Op : getAllOperands ()) {
1028
1043
OwnershipCompatibilityUseChecker (getModule (), Op).check (Self);
0 commit comments