Skip to content

Commit

Permalink
SIL: Better verifier check for references from fragile functions
Browse files Browse the repository at this point in the history
  • Loading branch information
slavapestov committed Apr 8, 2016
1 parent 5aa99fa commit 370b16b
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 30 deletions.
2 changes: 1 addition & 1 deletion include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ class SILFunction

/// verify - Run the IR verifier to make sure that the SILFunction follows
/// invariants.
void verify() const;
void verify(bool SingleFunction=true) const;

/// Pretty-print the SILFunction.
void dump(bool Verbose) const;
Expand Down
7 changes: 1 addition & 6 deletions lib/SIL/SILFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,6 @@ bool SILFunction::hasValidLinkageForFragileRef() const {
if (isFragile())
return true;

// If the function is a forward declaration, we may have not deserialized
// the body yet.
if (isExternalDeclaration())
return true;

// Fragile functions can reference 'static inline' functions imported
// from C.
if (hasForeignBody())
Expand All @@ -536,7 +531,7 @@ bool SILFunction::hasValidLinkageForFragileRef() const {
return true;

// Otherwise, only public functions can be referenced.
return hasPublicVisibility(linkage);
return hasPublicVisibility(getLinkage());
}

/// Helper method which returns true if the linkage of the SILFunction
Expand Down
31 changes: 8 additions & 23 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
Lowering::TypeConverter &TC;
const SILInstruction *CurInstruction = nullptr;
DominanceInfo *Dominance = nullptr;
bool SingleFunction = true;

SILVerifier(const SILVerifier&) = delete;
void operator=(const SILVerifier&) = delete;
Expand Down Expand Up @@ -410,9 +411,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
}
}

SILVerifier(const SILFunction &F)
SILVerifier(const SILFunction &F, bool SingleFunction=true)
: M(F.getModule().getSwiftModule()), F(F), TC(F.getModule().Types),
Dominance(nullptr) {
Dominance(nullptr), SingleFunction(SingleFunction) {
if (F.isExternalDeclaration())
return;

Expand Down Expand Up @@ -902,31 +903,15 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
verifyLLVMIntrinsic(BI, BI->getIntrinsicInfo().ID);
}

/// Returns true if \p FRI is only used as a callee and will always be
/// inlined at those call sites.
static bool isAlwaysInlined(FunctionRefInst *FRI) {
if (FRI->getReferencedFunction()->getInlineStrategy() != AlwaysInline &&
!FRI->getReferencedFunction()->isTransparent()) {
return false;
}

for (auto use : FRI->getUses()) {
auto site = FullApplySite::isa(use->getUser());
if (!site || site.getCallee() != FRI)
return false;
}
return true;
}

void checkFunctionRefInst(FunctionRefInst *FRI) {
auto fnType = requireObjectType(SILFunctionType, FRI,
"result of function_ref");
require(!fnType->getExtInfo().hasContext(),
"function_ref should have a context-free function result");
if (F.isFragile()) {
SILFunction *RefF = FRI->getReferencedFunction();
require(isAlwaysInlined(FRI)
|| RefF->hasValidLinkageForFragileRef(),
require((SingleFunction && RefF->isExternalDeclaration()) ||
RefF->hasValidLinkageForFragileRef(),
"function_ref inside fragile function cannot "
"reference a private or hidden symbol");
}
Expand Down Expand Up @@ -3128,12 +3113,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {

/// verify - Run the SIL verifier to make sure that the SILFunction follows
/// invariants.
void SILFunction::verify() const {
void SILFunction::verify(bool SingleFunction) const {
#ifndef NDEBUG
// Please put all checks in visitSILFunction in SILVerifier, not here. This
// ensures that the pretty stack trace in the verifier is included with the
// back trace when the verifier crashes.
SILVerifier(*this).verify();
SILVerifier(*this, SingleFunction).verify();
#endif
}

Expand Down Expand Up @@ -3274,7 +3259,7 @@ void SILModule::verify() const {
llvm::errs() << "Symbol redefined: " << f.getName() << "!\n";
assert(false && "triggering standard assertion failure routine");
}
f.verify();
f.verify(/*SingleFunction=*/ false);
}

// Check all globals.
Expand Down

0 comments on commit 370b16b

Please sign in to comment.