@@ -7668,57 +7668,111 @@ void SILVTable::verify(const SILModule &M) const {
76687668}
76697669
76707670// / Verify that a witness table follows invariants.
7671- void SILWitnessTable::verify (const SILModule &M ) const {
7672- if (!verificationEnabled (M ))
7671+ void SILWitnessTable::verify (const SILModule &mod ) const {
7672+ if (!verificationEnabled (mod ))
76737673 return ;
76747674
76757675 if (isDeclaration ())
76767676 assert (getEntries ().empty () &&
76777677 " A witness table declaration should not have any entries." );
76787678
7679- for (const Entry &E : getEntries ())
7680- if (E.getKind () == SILWitnessTable::WitnessKind::Method) {
7681- SILFunction *F = E.getMethodWitness ().Witness ;
7682- if (F) {
7683- // If a SILWitnessTable is going to be serialized, it must only
7684- // reference public or serializable functions.
7685- if (isAnySerialized ()) {
7686- assert (F->hasValidLinkageForFragileRef (getSerializedKind ()) &&
7687- " Fragile witness tables should not reference "
7688- " less visible functions." );
7689- }
7679+ for (const Entry &entry : getEntries ()) {
7680+ if (entry.getKind () != SILWitnessTable::WitnessKind::Method)
7681+ continue ;
7682+
7683+ auto *witnessFunction = entry.getMethodWitness ().Witness ;
7684+ if (!witnessFunction)
7685+ continue ;
7686+
7687+ // If a SILWitnessTable is going to be serialized, it must only
7688+ // reference public or serializable functions.
7689+ if (isAnySerialized ()) {
7690+ assert (
7691+ witnessFunction->hasValidLinkageForFragileRef (getSerializedKind ()) &&
7692+ " Fragile witness tables should not reference "
7693+ " less visible functions." );
7694+ }
76907695
7691- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7696+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
76927697 SILFunctionTypeRepresentation::WitnessMethod &&
7693- " Witnesses must have witness_method representation." );
7698+ " Witnesses must have witness_method representation." );
7699+
7700+ if (mod.getStage () != SILStage::Lowered &&
7701+ !mod.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
7702+ // Note the direction of the compatibility check: the witness
7703+ // function must be compatible with being used as the requirement
7704+ // type.
7705+ auto baseInfo = witnessFunction->getModule ().Types .getConstantInfo (
7706+ TypeExpansionContext::minimal (),
7707+ entry.getMethodWitness ().Requirement );
7708+ SmallString<32 > baseName;
7709+ {
7710+ llvm::raw_svector_ostream os (baseName);
7711+ entry.getMethodWitness ().Requirement .print (os);
76947712 }
7713+
7714+ SILVerifier (*witnessFunction, /* calleeCache=*/ nullptr ,
7715+ /* SingleFunction=*/ true ,
7716+ /* checkLinearLifetime=*/ false )
7717+ .requireABICompatibleFunctionTypes (
7718+ witnessFunction->getLoweredFunctionType (),
7719+ baseInfo.getSILType ().castTo <SILFunctionType>(),
7720+ " witness table entry for " + baseName + " must be ABI-compatible" ,
7721+ *witnessFunction);
76957722 }
7723+ }
76967724}
76977725
76987726// / Verify that a default witness table follows invariants.
7699- void SILDefaultWitnessTable::verify (const SILModule &M) const {
7700- #ifndef NDEBUG
7701- for (const Entry &E : getEntries ()) {
7727+ void SILDefaultWitnessTable::verify (const SILModule &mod) const {
7728+ if (!verificationEnabled (mod))
7729+ return ;
7730+
7731+ for (const Entry &entry : getEntries ()) {
77027732 // FIXME: associated type witnesses.
7703- if (!E .isValid () || E .getKind () != SILWitnessTable::Method)
7733+ if (!entry .isValid () || entry .getKind () != SILWitnessTable::Method)
77047734 continue ;
77057735
7706- SILFunction *F = E .getMethodWitness ().Witness ;
7707- if (!F )
7736+ auto *witnessFunction = entry .getMethodWitness ().Witness ;
7737+ if (!witnessFunction )
77087738 continue ;
77097739
77107740#if 0
77117741 // FIXME: For now, all default witnesses are private.
7712- assert(F ->hasValidLinkageForFragileRef(IsSerialized) &&
7742+ assert(witnessFunction ->hasValidLinkageForFragileRef(IsSerialized) &&
77137743 "Default witness tables should not reference "
77147744 "less visible functions.");
77157745#endif
77167746
7717- assert (F ->getLoweredFunctionType ()->getRepresentation () ==
7718- SILFunctionTypeRepresentation::WitnessMethod &&
7747+ assert (witnessFunction ->getLoweredFunctionType ()->getRepresentation () ==
7748+ SILFunctionTypeRepresentation::WitnessMethod &&
77197749 " Default witnesses must have witness_method representation." );
7750+
7751+ if (mod.getStage () != SILStage::Lowered &&
7752+ !mod.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
7753+ // Note the direction of the compatibility check: the witness
7754+ // function must be compatible with being used as the requirement
7755+ // type.
7756+ auto baseInfo = witnessFunction->getModule ().Types .getConstantInfo (
7757+ TypeExpansionContext::minimal (),
7758+ entry.getMethodWitness ().Requirement );
7759+ SmallString<32 > baseName;
7760+ {
7761+ llvm::raw_svector_ostream os (baseName);
7762+ entry.getMethodWitness ().Requirement .print (os);
7763+ }
7764+
7765+ SILVerifier (*witnessFunction, /* calleeCache=*/ nullptr ,
7766+ /* SingleFunction=*/ true ,
7767+ /* checkLinearLifetime=*/ false )
7768+ .requireABICompatibleFunctionTypes (
7769+ witnessFunction->getLoweredFunctionType (),
7770+ baseInfo.getSILType ().castTo <SILFunctionType>(),
7771+ " default witness table entry for " + baseName +
7772+ " must be ABI-compatible" ,
7773+ *witnessFunction);
7774+ }
77207775 }
7721- #endif
77227776}
77237777
77247778// / Verify that a global variable follows invariants.
0 commit comments