Skip to content

SILGen: Plumb the source location of force-unwraps through the intrinsic. #2957

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion lib/SILGen/SILGenConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,46 @@ static CanType getOptionalValueType(SILType optType,
return generic.getGenericArgs()[0];
}

static void emitSourceLocationArgs(SILGenFunction &gen,
SILLocation loc,
ManagedValue (&args)[4]) {
auto &ctx = gen.getASTContext();
auto sourceLoc = loc.getSourceLoc();

StringRef filename = "";
unsigned line = 0;
if (sourceLoc.isValid()) {
unsigned bufferID = ctx.SourceMgr.findBufferContainingLoc(sourceLoc);
filename = ctx.SourceMgr.getIdentifierForBuffer(bufferID);
line = ctx.SourceMgr.getLineAndColumn(sourceLoc).first;
}

bool isASCII = true;
for (unsigned char c : filename) {
if (c > 127) {
isASCII = false;
break;
}
}

auto wordTy = SILType::getBuiltinWordType(ctx);
auto i1Ty = SILType::getBuiltinIntegerType(1, ctx);

// File
SILValue literal = gen.B.createStringLiteral(loc, filename,
StringLiteralInst::Encoding::UTF8);
args[0] = ManagedValue::forUnmanaged(literal);
// File length
literal = gen.B.createIntegerLiteral(loc, wordTy, filename.size());
args[1] = ManagedValue::forUnmanaged(literal);
// File is ascii
literal = gen.B.createIntegerLiteral(loc, i1Ty, isASCII);
args[2] = ManagedValue::forUnmanaged(literal);
// Line
literal = gen.B.createIntegerLiteral(loc, wordTy, line);
args[3] = ManagedValue::forUnmanaged(literal);
}

void SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
SILValue optional) {
OptionalTypeKind OTK;
Expand All @@ -181,7 +221,10 @@ void SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
// Call the standard library implementation of _diagnoseUnexpectedNilOptional.
if (auto diagnoseFailure =
getASTContext().getDiagnoseUnexpectedNilOptional(nullptr)) {
emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, {}, {},
ManagedValue args[4];
emitSourceLocationArgs(*this, loc, args);

emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, {}, args,
SGFContext());
}

Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2033,7 +2033,7 @@ getMagicFunctionString(SILGenFunction &gen) {

RValue RValueEmitter::
visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) {
ASTContext &Ctx = SGF.SGM.M.getASTContext();
ASTContext &Ctx = SGF.getASTContext();
SILType Ty = SGF.getLoweredLoadableType(E->getType());
SourceLoc Loc;

Expand Down
11 changes: 9 additions & 2 deletions stdlib/public/core/Optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,16 @@ extension Optional : CustomReflectable {

@_transparent
public // COMPILER_INTRINSIC
func _diagnoseUnexpectedNilOptional() {
func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer,
_filenameLength: Builtin.Word,
_filenameIsASCII: Builtin.Int1,
_line: Builtin.Word) {
_preconditionFailure(
"unexpectedly found nil while unwrapping an Optional value")
"unexpectedly found nil while unwrapping an Optional value",
file: StaticString(_start: _filenameStart,
utf8CodeUnitCount: _filenameLength,
isASCII: _filenameIsASCII),
line: UInt(_line))
}

public func == <T: Equatable> (lhs: T?, rhs: T?) -> Bool {
Expand Down
8 changes: 4 additions & 4 deletions test/SILGen/optional_lvalue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// CHECK-LABEL: sil hidden @_TF15optional_lvalue22assign_optional_lvalueFTRGSqSi_Si_T_
// CHECK: [[SHADOW:%.*]] = alloc_box $Optional<Int>
// CHECK: [[PB:%.*]] = project_box [[SHADOW]]
// CHECK: [[PRECOND:%.*]] = function_ref @_TFs30_diagnoseUnexpectedNilOptionalFT_T_
// CHECK: apply [[PRECOND]]()
// CHECK: [[PRECOND:%.*]] = function_ref @_TFs30_diagnoseUnexpectedNilOptional
// CHECK: apply [[PRECOND]](
// CHECK: [[PAYLOAD:%.*]] = unchecked_take_enum_data_addr [[PB]] : $*Optional<Int>, #Optional.some!enumelt.1
// CHECK: assign {{%.*}} to [[PAYLOAD]]
func assign_optional_lvalue(_ x: inout Int?, _ y: Int) {
Expand All @@ -14,8 +14,8 @@ func assign_optional_lvalue(_ x: inout Int?, _ y: Int) {
// CHECK-LABEL: sil hidden @_TF15optional_lvalue17assign_iuo_lvalueFTRGSQSi_Si_T_
// CHECK: [[SHADOW:%.*]] = alloc_box $ImplicitlyUnwrappedOptional<Int>
// CHECK: [[PB:%.*]] = project_box [[SHADOW]]
// CHECK: [[PRECOND:%.*]] = function_ref @_TFs30_diagnoseUnexpectedNilOptionalFT_T_
// CHECK: apply [[PRECOND]]()
// CHECK: [[PRECOND:%.*]] = function_ref @_TFs30_diagnoseUnexpectedNilOptional
// CHECK: apply [[PRECOND]](
// CHECK: [[PAYLOAD:%.*]] = unchecked_take_enum_data_addr [[PB]] : $*ImplicitlyUnwrappedOptional<Int>, #ImplicitlyUnwrappedOptional.some!enumelt.1
// CHECK: assign {{%.*}} to [[PAYLOAD]]
func assign_iuo_lvalue(_ x: inout Int!, _ y: Int) {
Expand Down