33
33
#include " swift/SIL/SILModule.h"
34
34
#include " swift/SIL/SILOpenedArchetypesTracker.h"
35
35
#include " swift/SIL/SILVTable.h"
36
+ #include " swift/SIL/SILVTableVisitor.h"
36
37
#include " swift/SIL/SILVisitor.h"
37
38
#include " swift/SIL/BasicBlockUtils.h"
38
39
#include " swift/SIL/TypeLowering.h"
@@ -2554,7 +2555,56 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2554
2555
F.getASTContext ());
2555
2556
return SILType::getPrimitiveObjectType (fnTy);
2556
2557
}
2557
-
2558
+
2559
+ // / Visitor class that checks whether a given decl ref has an entry in the
2560
+ // / class's vtable.
2561
+ class VerifyClassMethodVisitor
2562
+ : public SILVTableVisitor<VerifyClassMethodVisitor>
2563
+ {
2564
+ public:
2565
+ SILDeclRef MethodToSee;
2566
+ bool Seen = false ;
2567
+
2568
+ VerifyClassMethodVisitor (ClassDecl *theClass,
2569
+ SILDeclRef method)
2570
+ : MethodToSee(method)
2571
+ {
2572
+ addVTableEntries (theClass);
2573
+ }
2574
+
2575
+ bool methodMatches (SILDeclRef method) {
2576
+ auto methodToCheck = MethodToSee;
2577
+ do {
2578
+ if (method == methodToCheck) {
2579
+ return true ;
2580
+ }
2581
+ } while ((methodToCheck = methodToCheck.getNextOverriddenVTableEntry ()));
2582
+
2583
+ return false ;
2584
+ }
2585
+
2586
+ void addMethod (SILDeclRef method) {
2587
+ if (Seen)
2588
+ return ;
2589
+ if (methodMatches (method))
2590
+ Seen = true ;
2591
+ }
2592
+
2593
+ void addMethodOverride (SILDeclRef base, SILDeclRef derived) {
2594
+ if (Seen)
2595
+ return ;
2596
+ // The derived method should already have been checked.
2597
+ // Test against the overridden base.
2598
+ if (methodMatches (base))
2599
+ Seen = true ;
2600
+ }
2601
+
2602
+
2603
+ void addPlaceholder (MissingMemberDecl *) {
2604
+ /* no-op */
2605
+ }
2606
+ };
2607
+
2558
2608
void checkClassMethodInst (ClassMethodInst *CMI) {
2559
2609
auto member = CMI->getMember ();
2560
2610
auto overrideTy = TC.getConstantOverrideType (member);
@@ -2577,6 +2627,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2577
2627
" foreign method cannot be dispatched natively" );
2578
2628
require (!isa<ExtensionDecl>(member.getDecl ()->getDeclContext ()),
2579
2629
" extension method cannot be dispatched natively" );
2630
+
2631
+ // The method ought to appear in the class vtable.
2632
+ require (VerifyClassMethodVisitor (
2633
+ operandType.getASTType ()->getMetatypeInstanceType ()
2634
+ ->getClassOrBoundGenericClass (),
2635
+ member).Seen ,
2636
+ " method does not appear in the class's vtable" );
2580
2637
}
2581
2638
2582
2639
void checkSuperMethodInst (SuperMethodInst *CMI) {
@@ -2607,6 +2664,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2607
2664
2608
2665
require (methodClass->getClassOrBoundGenericClass (),
2609
2666
" super_method must look up a class method" );
2667
+
2668
+ // The method ought to appear in the class vtable.
2669
+ require (VerifyClassMethodVisitor (
2670
+ operandType.getASTType ()->getMetatypeInstanceType ()
2671
+ ->getClassOrBoundGenericClass (),
2672
+ member).Seen ,
2673
+ " method does not appear in the class's vtable" );
2610
2674
}
2611
2675
2612
2676
void checkObjCMethodInst (ObjCMethodInst *OMI) {
0 commit comments