SIL: Change rule regarding shared_external linkage

The existence of a shared_external function in itself is not
an error; it just means we deserialized a witness table or
vtable but did not need to deserialize a thunk.

However, a direct reference to such a function is an error,
because we should have deserialized the body in that case.

This fixes a crasher, but the SIL crashers are kind of silly
because the SIL parser does not try at all not to crash on
invalid input.
This commit is contained in:
Slava Pestov
2017-03-29 00:16:46 -07:00
parent 589107aa03
commit 8201eaaa60
3 changed files with 20 additions and 7 deletions

View File

@@ -1131,8 +1131,25 @@ public:
"result of function_ref");
require(!fnType->getExtInfo().hasContext(),
"function_ref should have a context-free function result");
// Note: in SingleFunction mode, we relax some of these checks because
// we may not have linked everything yet.
SILFunction *RefF = FRI->getReferencedFunction();
// A direct reference to a shared_external declaration is an error; we
// should have deserialized a body.
if (RefF->isExternalDeclaration()) {
require(SingleFunction ||
!hasSharedVisibility(RefF->getLinkage()) ||
RefF->hasForeignBody(),
"external declarations of SILFunctions with shared visibility is "
"not allowed");
}
// A direct reference to a non-public or shared but not fragile function
// from a fragile function is an error.
if (F.isSerialized()) {
SILFunction *RefF = FRI->getReferencedFunction();
require((SingleFunction && RefF->isExternalDeclaration()) ||
RefF->hasValidLinkageForFragileRef(),
"function_ref inside fragile function cannot "
@@ -3912,9 +3929,6 @@ public:
assert(F->isAvailableExternally() &&
"external declaration of internal SILFunction not allowed");
assert(!hasSharedVisibility(F->getLinkage()) &&
"external declarations of SILFunctions with shared visibility is not "
"allowed");
// If F is an external declaration, there is nothing further to do,
// return.
return;