@@ -7663,57 +7663,111 @@ void SILVTable::verify(const SILModule &M) const {
76637663}
76647664
76657665// / 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 ))
76687668 return ;
76697669
76707670 if (isDeclaration ())
76717671 assert (getEntries ().empty () &&
76727672 " A witness table declaration should not have any entries." );
76737673
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+ }
76857690
7686- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7691+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
76877692 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);
76897707 }
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);
76907717 }
7718+ }
76917719}
76927720
76937721// / 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 ()) {
76977727 // FIXME: associated type witnesses.
7698- if (!E .isValid () || E .getKind () != SILWitnessTable::Method)
7728+ if (!entry .isValid () || entry .getKind () != SILWitnessTable::Method)
76997729 continue ;
77007730
7701- SILFunction *F = E .getMethodWitness ().Witness ;
7702- if (!F )
7731+ auto *witnessFunction = entry .getMethodWitness ().Witness ;
7732+ if (!witnessFunction )
77037733 continue ;
77047734
77057735#if 0
77067736 // FIXME: For now, all default witnesses are private.
7707- assert(F ->hasValidLinkageForFragileRef(IsSerialized) &&
7737+ assert(witnessFunction ->hasValidLinkageForFragileRef(IsSerialized) &&
77087738 "Default witness tables should not reference "
77097739 "less visible functions.");
77107740#endif
77117741
7712- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7713- SILFunctionTypeRepresentation::WitnessMethod &&
7742+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
7743+ SILFunctionTypeRepresentation::WitnessMethod &&
77147744 " 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+ }
77157770 }
7716- #endif
77177771}
77187772
77197773// / Verify that a global variable follows invariants.
0 commit comments