Skip to content

Runtime: Include source location information in log messages about deprecated implicit Objective-C entry points. #9671

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
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
2 changes: 1 addition & 1 deletion include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ FUNCTION(GetInitializedObjCClass, swift_getInitializedObjCClass, RegisterPreserv
FUNCTION(Swift3ImplicitObjCEntrypoint, swift_objc_swift3ImplicitObjCEntrypoint,
DefaultCC,
RETURNS(VoidTy),
ARGS(ObjCPtrTy, ObjCSELTy),
ARGS(ObjCPtrTy, ObjCSELTy, Int8PtrTy, SizeTy, SizeTy, SizeTy),
ATTRS(NoUnwind))

#endif
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1783,7 +1783,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
return getTSanInoutAccess(Context, Id);

case BuiltinValueKind::Swift3ImplicitObjCEntrypoint:
return getBuiltinFunction(Id, {}, TupleType::getEmpty(Context));
return getBuiltinFunction(Id,
{},
TupleType::getEmpty(Context));
}

llvm_unreachable("bad builtin value!");
Expand Down
28 changes: 19 additions & 9 deletions lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,20 +860,30 @@ if (Builtin.ID == BuiltinValueKind::id) { \
}

if (Builtin.ID == BuiltinValueKind::Swift3ImplicitObjCEntrypoint) {
llvm::Value *args[2];
llvm::Value *entrypointArgs[6];
auto argIter = IGF.CurFn->arg_begin();

// self
args[0] = &*argIter++;
if (args[0]->getType() != IGF.IGM.ObjCPtrTy)
args[0] = IGF.Builder.CreateBitCast(args[0], IGF.IGM.ObjCPtrTy);
entrypointArgs[0] = &*argIter++;
if (entrypointArgs[0]->getType() != IGF.IGM.ObjCPtrTy)
entrypointArgs[0] = IGF.Builder.CreateBitCast(entrypointArgs[0], IGF.IGM.ObjCPtrTy);

// _cmd
args[1] = &*argIter;
if (args[1]->getType() != IGF.IGM.ObjCSELTy)
args[1] = IGF.Builder.CreateBitCast(args[1], IGF.IGM.ObjCSELTy);

IGF.Builder.CreateCall(IGF.IGM.getSwift3ImplicitObjCEntrypointFn(), args);
entrypointArgs[1] = &*argIter;
if (entrypointArgs[1]->getType() != IGF.IGM.ObjCSELTy)
entrypointArgs[1] = IGF.Builder.CreateBitCast(entrypointArgs[1], IGF.IGM.ObjCSELTy);

// Filename pointer
entrypointArgs[2] = args.claimNext();
// Filename length
entrypointArgs[3] = args.claimNext();
// Line
entrypointArgs[4] = args.claimNext();
// Column
entrypointArgs[5] = args.claimNext();

IGF.Builder.CreateCall(IGF.IGM.getSwift3ImplicitObjCEntrypointFn(),
entrypointArgs);
return;
}

Expand Down
19 changes: 17 additions & 2 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,8 +1050,23 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
if (attr->isSwift3Inferred() &&
!decl->getAttrs().hasAttribute<DynamicAttr>() &&
!getASTContext().LangOpts.isSwiftVersion3()) {
B.createBuiltin(loc, getASTContext().getIdentifier("swift3ImplicitObjCEntrypoint"),
getModule().Types.getEmptyTupleType(), { }, { });

// Get the starting source location of the declaration so we can say
// exactly where to stick '@objc'.
SourceLoc objcInsertionLoc =
decl->getAttributeInsertionLoc(/*modifier*/ false);

auto objcInsertionLocArgs
= emitSourceLocationArgs(objcInsertionLoc, loc);

B.createBuiltin(loc,
getASTContext().getIdentifier("swift3ImplicitObjCEntrypoint"),
getModule().Types.getEmptyTupleType(), { }, {
objcInsertionLocArgs.filenameStartPointer.forward(*this),
objcInsertionLocArgs.filenameLength.forward(*this),
objcInsertionLocArgs.line.forward(*this),
objcInsertionLocArgs.column.forward(*this)
});
}
}
}
Expand Down
48 changes: 29 additions & 19 deletions lib/SILGen/SILGenConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,18 @@ getOptionalSomeValue(SILLocation loc, ManagedValue value,
return emitManagedRValueWithCleanup(result, optTL);
}

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

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

bool isASCII = true;
Expand All @@ -160,19 +160,24 @@ static void emitSourceLocationArgs(SILGenFunction &gen,
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);
SourceLocArgs result;
SILValue literal = B.createStringLiteral(emitLoc, filename,
StringLiteralInst::Encoding::UTF8);
result.filenameStartPointer = ManagedValue::forUnmanaged(literal);
// File length
literal = gen.B.createIntegerLiteral(loc, wordTy, filename.size());
args[1] = ManagedValue::forUnmanaged(literal);
literal = B.createIntegerLiteral(emitLoc, wordTy, filename.size());
result.filenameLength = ManagedValue::forUnmanaged(literal);
// File is ascii
literal = gen.B.createIntegerLiteral(loc, i1Ty, isASCII);
args[2] = ManagedValue::forUnmanaged(literal);
literal = B.createIntegerLiteral(emitLoc, i1Ty, isASCII);
result.filenameIsAscii = ManagedValue::forUnmanaged(literal);
// Line
literal = gen.B.createIntegerLiteral(loc, wordTy, line);
args[3] = ManagedValue::forUnmanaged(literal);
literal = B.createIntegerLiteral(emitLoc, wordTy, line);
result.line = ManagedValue::forUnmanaged(literal);
// Column
literal = B.createIntegerLiteral(emitLoc, wordTy, column);
result.column = ManagedValue::forUnmanaged(literal);

return result;
}

ManagedValue
Expand Down Expand Up @@ -204,10 +209,15 @@ SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
// Call the standard library implementation of _diagnoseUnexpectedNilOptional.
if (auto diagnoseFailure =
getASTContext().getDiagnoseUnexpectedNilOptional(nullptr)) {
ManagedValue args[4];
emitSourceLocationArgs(*this, loc, args);
auto args = emitSourceLocationArgs(loc.getSourceLoc(), loc);

emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, SubstitutionMap(), args,
emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, SubstitutionMap(),
{
args.filenameStartPointer,
args.filenameLength,
args.filenameIsAscii,
args.line
},
SGFContext());
}

Expand Down
17 changes: 17 additions & 0 deletions lib/SILGen/SILGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,23 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
ManagedValue getOptionalSomeValue(SILLocation loc, ManagedValue value,
const TypeLowering &optTL);

struct SourceLocArgs {
ManagedValue filenameStartPointer,
filenameLength,
filenameIsAscii,
line,
column;
};

/// Emit raw lowered arguments for a runtime diagnostic to report the given
/// source location:
/// - The first three arguments are the components necessary to construct
/// a StaticString for the filename: start pointer, length, and
/// "is ascii" bit.
/// - The fourth argument is the line number.
SourceLocArgs
emitSourceLocationArgs(SourceLoc loc, SILLocation emitLoc);

/// \brief Emit a call to the library intrinsic _doesOptionalHaveValue.
///
/// The result is a Builtin.Int1.
Expand Down
16 changes: 13 additions & 3 deletions stdlib/public/runtime/SwiftObject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,10 @@ static bool usesNativeSwiftReferenceCounting_nonNull(

SWIFT_CC(swift)
SWIFT_RUNTIME_EXPORT
void swift_objc_swift3ImplicitObjCEntrypoint(id self, SEL selector) {
void swift_objc_swift3ImplicitObjCEntrypoint(id self, SEL selector,
const char *filename,
size_t filenameLength,
size_t line, size_t column) {
// Figure out how much reporting we want by querying the environment
// variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT. We have four meaningful
// levels:
Expand Down Expand Up @@ -1398,10 +1401,17 @@ void swift_objc_swift3ImplicitObjCEntrypoint(id self, SEL selector) {
bool isInstanceMethod = !class_isMetaClass(object_getClass(self));
void (*reporter)(uint32_t, const char *, ...) =
reportLevel > 2 ? swift::fatalError : swift::warning;

if (filenameLength > INT_MAX)
filenameLength = INT_MAX;

reporter(
flags,
"***Swift runtime: entrypoint %c[%s %s] generated by implicit @objc "
"inference is deprecated and will be removed in Swift 4\n",
"*** %*s:%zu:%zu: implicit Objective-C entrypoint %c[%s %s] "
"is deprecated and will be removed in Swift 4; "
"add explicit '@objc' to the declaration to emit the Objective-C "
"entrypoint in Swift 4 and suppress this message",
(int)filenameLength, filename, line, column,
isInstanceMethod ? '-' : '+',
class_getName([self class]),
sel_getName(selector));
Expand Down
6 changes: 4 additions & 2 deletions test/IRGen/objc_deprecated_objc_thunks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// REQUIRES: CPU=x86_64
// REQUIRES: objc_interop

// CHECK-SWIFT4: [[FILENAME_STR:@.*]] = private unnamed_addr constant {{.*}}.swift\00"

import Foundation

class ObjCSubclass : NSObject {
Expand All @@ -14,8 +16,8 @@ class ObjCSubclass : NSObject {
// CHECK-SWIFT4-LABEL: define hidden void @_T0016objc_deprecated_A7_thunks12ObjCSubclassC3fooyyFTo(%0*, i8*)
// CHECK-SWIFT4: entry:
// CHECK-SWIFT4: [[SELF:%[0-9]+]] = bitcast %0* %0 to %objc_object*
// CHECK-SWIFT4-NEXT: call void @swift_objc_swift3ImplicitObjCEntrypoint(%objc_object* [[SELF]], i8* %1)
// CHECK-SWIFT4-NEXT: call void @swift_objc_swift3ImplicitObjCEntrypoint(%objc_object* [[SELF]], i8* %1, i8* getelementptr inbounds ({{.*}}[[FILENAME_STR]]{{.*}}), i64 [[FILENAME_LENGTH:[0-9]+]], i64 13, i64 3)

// CHECK-SWIFT3-LABEL: define hidden void @_T0016objc_deprecated_A7_thunks12ObjCSubclassC3fooyyFTo(%0*, i8*)
// CHECK-SWIFT3: entry:
// CHECK-SWIFT3-NOT: call void @swift_objc_swift3ImplicitObjCEntrypoint(%objc_object* [[SELF]], i8* %1)
// CHECK-SWIFT3-NOT: call void @swift_objc_swift3ImplicitObjCEntrypoint
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ DeprecatedObjCInferenceTestSuite.test("messagingObjCInference") {
// CHECK_CRASH: ---Begin
fputs("---Begin\n", stderr)

// CHECK_WARNINGS: ***Swift runtime: entrypoint -[a.MyClass foo] generated by implicit @objc inference is deprecated and will be removed in Swift 4
// CHECK_CRASH: ***Swift runtime: entrypoint -[a.MyClass foo] generated by implicit @objc inference is deprecated and will be removed in Swift 4
// CHECK_WARNINGS: .swift:26:3: implicit Objective-C entrypoint -[a.MyClass foo]
// CHECK_CRASH: .swift:26:3: implicit Objective-C entrypoint -[a.MyClass foo]
x.perform(Selector(fooSel))

// CHECK_WARNINGS: ***Swift runtime: entrypoint +[a.MyClass bar] generated by implicit @objc inference is deprecated and will be removed in Swift 4
// CHECK_WARNINGS: .swift:27:3: implicit Objective-C entrypoint +[a.MyClass bar]
type(of: x).perform(Selector(barSel))

// CHECK_NOTHING-NEXT: ---End
Expand Down
66 changes: 58 additions & 8 deletions test/SILGen/objc_deprecated_objc_thunks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,89 @@ import Foundation
class ObjCSubclass : NSObject {
// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassCACyt7nothing_tcfcTo : $@convention(objc_method) (@owned ObjCSubclass) -> @owned ObjCSubclass {
// CHECK-SWIFT4: bb0(%0 : $ObjCSubclass):
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL:string_literal.*"]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
init(nothing: ()) { super.init() }

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC3fooyyFTo : $@convention(objc_method) (ObjCSubclass) -> ()
// CHECK-SWIFT4: bb0(%0 : $ObjCSubclass):
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
func foo() { }

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC3barSo8NSObjectCSgfgTo : $@convention(objc_method) (ObjCSubclass) -> @autoreleased Optional<NSObject>
// CHECK-SWIFT4: bb0(%0 : $ObjCSubclass):
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+12]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC3barSo8NSObjectCSgfsTo : $@convention(objc_method) (Optional<NSObject>, ObjCSubclass) -> () {
// CHECK-SWIFT4: %0 : $Optional<NSObject>, %1 : $ObjCSubclass
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
var bar: NSObject? = nil

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC9subscriptyXlSicfgTo : $@convention(objc_method) (Int, ObjCSubclass) -> @autoreleased AnyObject
// CHECK-SWIFT4: bb0(%0 : $Int, %1 : $ObjCSubclass):
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+12]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC9subscriptyXlSicfsTo : $@convention(objc_method) (AnyObject, Int, ObjCSubclass) ->
// CHECK-SWIFT4: bb0(%0 : $AnyObject, %1 : $Int, %2 : $ObjCSubclass):
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
subscript (i: Int) -> AnyObject { get { return self } set { } }

// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC9staticFooyyFZTo
// CHECK-SWIFT4: bb0
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
static func staticFoo() {}

// CHECK-SWIFT4-LABEL: sil hidden [thunk] [noinline] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC13dontInlineFooyyFTo
// CHECK-SWIFT4: bb0
// CHECK-SWIFT4-NEXT: [[FILENAME:%.*]] = [[FILENAME_LITERAL]]
// CHECK-SWIFT4-NEXT: [[LENGTH:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[IS_ASCII:%.*]] = integer_literal
// CHECK-SWIFT4-NEXT: [[LINE:%.*]] = integer_literal $Builtin.Word, [[@LINE+3]]
// CHECK-SWIFT4-NEXT: [[COLUMN:%.*]] = integer_literal $Builtin.Word, 3
// CHECK-SWIFT4-NEXT: builtin "swift3ImplicitObjCEntrypoint"([[FILENAME]] : $Builtin.RawPointer, [[LENGTH]] : $Builtin.Word, [[LINE]] : $Builtin.Word, [[COLUMN]] : $Builtin.Word) : $()
@inline(never) func dontInlineFoo() {}
}

extension ObjCSubclass {
// CHECK-SWIFT4-LABEL: sil hidden [thunk] @_T0016objc_deprecated_A7_thunks12ObjCSubclassC13falsePositiveyyFTo : $@convention(objc_method) (ObjCSubclass) -> ()
// CHECK-SWIFT4: bb0(%0 : $ObjCSubclass):
// CHECK-SWIFT4-NOT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT4-NOT: builtin "swift3ImplicitObjCEntrypoint"
// CHECK-SWIFT4: return
func falsePositive() { }
}

// CHECK-SWIFT3-NOT: builtin "swift3ImplicitObjCEntrypoint"() : $()
// CHECK-SWIFT3-NOT: builtin "swift3ImplicitObjCEntrypoint"