@@ -7663,57 +7663,111 @@ void SILVTable::verify(const SILModule &M) const {
7663
7663
}
7664
7664
7665
7665
// / Verify that a witness table follows invariants.
7666
- void SILWitnessTable::verify (const SILModule &M ) const {
7667
- if (!verificationEnabled (M ))
7666
+ void SILWitnessTable::verify (const SILModule &mod ) const {
7667
+ if (!verificationEnabled (mod ))
7668
7668
return ;
7669
7669
7670
7670
if (isDeclaration ())
7671
7671
assert (getEntries ().empty () &&
7672
7672
" A witness table declaration should not have any entries." );
7673
7673
7674
- for (const Entry &E : getEntries ())
7675
- if (E.getKind () == SILWitnessTable::WitnessKind::Method) {
7676
- SILFunction *F = E.getMethodWitness ().Witness ;
7677
- if (F) {
7678
- // If a SILWitnessTable is going to be serialized, it must only
7679
- // reference public or serializable functions.
7680
- if (isAnySerialized ()) {
7681
- assert (F->hasValidLinkageForFragileRef (getSerializedKind ()) &&
7682
- " Fragile witness tables should not reference "
7683
- " less visible functions." );
7684
- }
7674
+ for (const Entry &entry : getEntries ()) {
7675
+ if (entry.getKind () != SILWitnessTable::WitnessKind::Method)
7676
+ continue ;
7677
+
7678
+ auto *witnessFunction = entry.getMethodWitness ().Witness ;
7679
+ if (!witnessFunction)
7680
+ continue ;
7681
+
7682
+ // If a SILWitnessTable is going to be serialized, it must only
7683
+ // reference public or serializable functions.
7684
+ if (isAnySerialized ()) {
7685
+ assert (
7686
+ witnessFunction->hasValidLinkageForFragileRef (getSerializedKind ()) &&
7687
+ " Fragile witness tables should not reference "
7688
+ " less visible functions." );
7689
+ }
7685
7690
7686
- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7691
+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
7687
7692
SILFunctionTypeRepresentation::WitnessMethod &&
7688
- " Witnesses must have witness_method representation." );
7693
+ " Witnesses must have witness_method representation." );
7694
+
7695
+ if (mod.getStage () != SILStage::Lowered &&
7696
+ !mod.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
7697
+ // Note the direction of the compatibility check: the witness
7698
+ // function must be compatible with being used as the requirement
7699
+ // type.
7700
+ auto baseInfo = witnessFunction->getModule ().Types .getConstantInfo (
7701
+ TypeExpansionContext::minimal (),
7702
+ entry.getMethodWitness ().Requirement );
7703
+ SmallString<32 > baseName;
7704
+ {
7705
+ llvm::raw_svector_ostream os (baseName);
7706
+ entry.getMethodWitness ().Requirement .print (os);
7689
7707
}
7708
+
7709
+ SILVerifier (*witnessFunction, /* calleeCache=*/ nullptr ,
7710
+ /* SingleFunction=*/ true ,
7711
+ /* checkLinearLifetime=*/ false )
7712
+ .requireABICompatibleFunctionTypes (
7713
+ witnessFunction->getLoweredFunctionType (),
7714
+ baseInfo.getSILType ().castTo <SILFunctionType>(),
7715
+ " witness table entry for " + baseName + " must be ABI-compatible" ,
7716
+ *witnessFunction);
7690
7717
}
7718
+ }
7691
7719
}
7692
7720
7693
7721
// / Verify that a default witness table follows invariants.
7694
- void SILDefaultWitnessTable::verify (const SILModule &M) const {
7695
- #ifndef NDEBUG
7696
- for (const Entry &E : getEntries ()) {
7722
+ void SILDefaultWitnessTable::verify (const SILModule &mod) const {
7723
+ if (!verificationEnabled (mod))
7724
+ return ;
7725
+
7726
+ for (const Entry &entry : getEntries ()) {
7697
7727
// FIXME: associated type witnesses.
7698
- if (!E .isValid () || E .getKind () != SILWitnessTable::Method)
7728
+ if (!entry .isValid () || entry .getKind () != SILWitnessTable::Method)
7699
7729
continue ;
7700
7730
7701
- SILFunction *F = E .getMethodWitness ().Witness ;
7702
- if (!F )
7731
+ auto *witnessFunction = entry .getMethodWitness ().Witness ;
7732
+ if (!witnessFunction )
7703
7733
continue ;
7704
7734
7705
7735
#if 0
7706
7736
// FIXME: For now, all default witnesses are private.
7707
- assert(F ->hasValidLinkageForFragileRef(IsSerialized) &&
7737
+ assert(witnessFunction ->hasValidLinkageForFragileRef(IsSerialized) &&
7708
7738
"Default witness tables should not reference "
7709
7739
"less visible functions.");
7710
7740
#endif
7711
7741
7712
- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7713
- SILFunctionTypeRepresentation::WitnessMethod &&
7742
+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
7743
+ SILFunctionTypeRepresentation::WitnessMethod &&
7714
7744
" Default witnesses must have witness_method representation." );
7745
+
7746
+ if (mod.getStage () != SILStage::Lowered &&
7747
+ !mod.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
7748
+ // Note the direction of the compatibility check: the witness
7749
+ // function must be compatible with being used as the requirement
7750
+ // type.
7751
+ auto baseInfo = witnessFunction->getModule ().Types .getConstantInfo (
7752
+ TypeExpansionContext::minimal (),
7753
+ entry.getMethodWitness ().Requirement );
7754
+ SmallString<32 > baseName;
7755
+ {
7756
+ llvm::raw_svector_ostream os (baseName);
7757
+ entry.getMethodWitness ().Requirement .print (os);
7758
+ }
7759
+
7760
+ SILVerifier (*witnessFunction, /* calleeCache=*/ nullptr ,
7761
+ /* SingleFunction=*/ true ,
7762
+ /* checkLinearLifetime=*/ false )
7763
+ .requireABICompatibleFunctionTypes (
7764
+ witnessFunction->getLoweredFunctionType (),
7765
+ baseInfo.getSILType ().castTo <SILFunctionType>(),
7766
+ " default witness table entry for " + baseName +
7767
+ " must be ABI-compatible" ,
7768
+ *witnessFunction);
7769
+ }
7715
7770
}
7716
- #endif
7717
7771
}
7718
7772
7719
7773
// / Verify that a global variable follows invariants.
0 commit comments