SIL verifier: Check that a class_method's type matches its override abstraction level.

Factor the code to compute an override's vtable type out of SILGen's emitVTableMethod into a method on TypeLowering, and use it to verify the type of class_method instructions. This catches rdar://problem/20874966 at SILGen time instead of letting the devirtualizer barf on it.

Swift SVN r29158
This commit is contained in:
Joe Groff
2015-05-30 00:41:49 +00:00
parent 86b4cf91ec
commit af66dfb73d
5 changed files with 78 additions and 31 deletions

View File

@@ -745,6 +745,13 @@ public:
ClassMethodInst(Loc, Operand, Member, MethodTy, Volatile));
}
/// Emit a class_method reference to the least derived overridden decl for
/// the given method, and upcast the "self" pointer to the matching superclass
/// type.
std::pair<ClassMethodInst *, SILValue>
emitClassMethod(SILLocation Loc, SILValue Self, SILDeclRef Member,
bool Volatile = false);
SuperMethodInst *createSuperMethod(SILLocation Loc, SILValue Operand,
SILDeclRef Member, SILType MethodTy,
bool Volatile = false) {

View File

@@ -681,6 +681,22 @@ public:
CanSILFunctionType getConstantFunctionType(SILDeclRef constant) {
return getConstantInfo(constant).SILFnType;
}
/// Returns the SILFunctionType the given declaration must use to override.
/// Will be the same as getConstantFunctionType if the declaration does
/// not override.
CanSILFunctionType getConstantOverrideType(SILDeclRef constant) {
// Fast path if the constant isn't overridden.
if (constant.getOverriddenVTableEntry().isNull())
return getConstantFunctionType(constant);
SILDeclRef base = constant;
while (SILDeclRef overridden = base.getOverridden())
base = overridden;
return getConstantOverrideType(constant, base);
}
CanSILFunctionType getConstantOverrideType(SILDeclRef constant,
SILDeclRef base);
/// Substitute the given function type so that it implements the
/// given substituted type.