Skip to content

Commit

Permalink
SIL parser: Import functions only mentioned in inline scopes as zombies.
Browse files Browse the repository at this point in the history
This fixes a SIL Verifier assertion when loading inlined functions from
textual SIL.

<rdar://problem/25174103>
  • Loading branch information
adrian-prantl committed Mar 16, 2016
1 parent 784f7a7 commit 8f72608
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/Parse/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,19 @@ using namespace swift;
namespace swift {
class SILParserTUState {
public:
SILParserTUState() {}
SILParserTUState(SILModule &M) : M(M) {}
~SILParserTUState();

SILModule &M;

/// This is all of the forward referenced functions with
/// the location for where the reference is.
llvm::DenseMap<Identifier,
std::pair<SILFunction*, SourceLoc>> ForwardRefFns;
/// A list of all functions foward-declared by a sil_scope.
std::vector<SILFunction *> PotentialZombieFns;

/// A map from textual .sil scope number to SILDebugScopes.
llvm::DenseMap<unsigned, SILDebugScope *> ScopeSlots;

/// Did we parse a sil_stage for this module?
Expand All @@ -51,7 +56,7 @@ namespace swift {
}

SILParserState::SILParserState(SILModule *M) : M(M) {
S = M ? new SILParserTUState() : nullptr;
S = M ? new SILParserTUState(*M) : nullptr;
}

SILParserState::~SILParserState() {
Expand All @@ -64,6 +69,13 @@ SILParserTUState::~SILParserTUState() {
if (Entry.second.second.isValid())
Diags->diagnose(Entry.second.second, diag::sil_use_of_undefined_value,
Entry.first.str());

// Turn any debug-info-only function declarations into zombies.
for (auto *Fn : PotentialZombieFns)
if (Fn->isExternalDeclaration()) {
Fn->setInlined();
M.eraseFunction(Fn);
}
}


Expand Down Expand Up @@ -4645,12 +4657,14 @@ bool Parser::parseSILScope() {
ScopeState.parseSILType(Ty, Ignored, true))
return true;

// The function doesn't exist yet. Create a zombie forward declaration.
auto FnTy = Ty.getAs<SILFunctionType>();
if (!FnTy || !Ty.isObject()) {
diagnose(FnLoc, diag::expected_sil_function_type);
return true;
}
ParentFn = ScopeState.getGlobalNameForReference(FnName, FnTy, FnLoc, true);
ScopeState.TUState.PotentialZombieFns.push_back(ParentFn);
}

SILDebugScope *InlinedAt = nullptr;
Expand Down
17 changes: 17 additions & 0 deletions test/SIL/Parser/sil_scope_inline_fn.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %target-sil-opt -enable-sil-verify-all -O %s | FileCheck %s

sil_scope 1 { loc "foo.sil":3:4 parent @foo : $@convention(thin) () -> () }
sil_scope 2 { loc "foo.sil":3:4 parent 1 }
sil_scope 3 { loc "bar.swift":1:2 parent @bar : $@convention(thin) () -> () }
sil_scope 4 { loc "bar.swift":1:2 parent 3 inlined_at 2 }

// CHECK: sil_scope 1 { loc "bar.swift":1:2 parent @bar : $@convention(thin) () -> () }
// CHECK: sil_scope 2 { loc "foo.sil":3:4 parent @foo : $@convention(thin) () -> () }
// CHECK: sil_scope 3 { loc "foo.sil":3:4 parent 2 }
// CHECK: sil_scope 4 { loc "bar.swift":1:2 parent 1 inlined_at 3 }

// foo
sil @foo : $@convention(thin) () -> () {
bb0:
return undef : $(), scope 4 // id: %1
}

0 comments on commit 8f72608

Please sign in to comment.