Commit Graph

195 Commits

Author SHA1 Message Date
Pavel Yaskevich
7bcd8ff203 [Sema] TypeWrappers: Replace self. with _storage. for immutable properties
Immutable properties cannot be re-assigned and don't have setters
which means that we cannot use `assign_by_wrapper` instruction to
handle `let` properties, but we can use a direct reference to
`_storage` property instead when immutable property appears as an
assignment destination and let read references go through a getter
still.
2022-10-04 13:24:46 -07:00
Pavel Yaskevich
445148c48c [Sema] TypeWrappers: Allow let properties to be managed by a type wrapper 2022-10-03 16:58:50 -07:00
Pavel Yaskevich
dcecf527e5 [SILOptimizer] TypeWrappers/NFC: Add tests for convenience initializers of wrapped types 2022-09-29 20:50:37 -07:00
Pavel Yaskevich
746457f346 [SILOptimizer] TypeWrappers: Implement self.$storage initialization injection
Inject a call to $Storage.init(...) which is then used to initialize
type wrapper property `$storage` via `self.$storage = <TypeWrapper>(memberwise: <storage>)`
call at each point where `_storage` becomes fully initialized.
2022-09-29 20:50:37 -07:00
Pavel Yaskevich
53bcf9ff67 [Sema] TypeWrappers: Implement @typeWrapperIgnored checking 2022-09-09 23:52:40 -07:00
Pavel Yaskevich
6d2edc2789 [Sema] TypeWrappers: Disable memberwise synthesis if type has designated init
If type has any user-defined designated initializers, let's not
synthesize a special memberwise initializer.
2022-09-02 17:58:48 -07:00
Pavel Yaskevich
347e85ddc4 [Sema] TypeWrappers: Add unamanged stored properties to the synthesized memberwise init
If a stored property would be in a default memberwise initializer
it would be added to the `init` synthesized for a type wrapped type
as well i.e. a `let` property without a default.
2022-08-26 12:25:22 -07:00
Pavel Yaskevich
0500f35537 [Sema] TypeWrappers: Synthesize init parameters for property wrapped members
Since properties with property wrappers are not supported, default
init synthesis needs to handle them as well by using correct interface
type depending on outer wrapper capabilities and setting correct
default expression.
2022-08-26 12:25:22 -07:00
Pavel Yaskevich
39b1566240 [Sema] TypeWrappers: convert variable init expr into initializer default
All of the stored properties are wrapped which means that their
initializers are subsummed and moved to the synthesized `init`
as default arguments.
2022-08-26 12:25:22 -07:00
Pavel Yaskevich
7d28a4fa78 [TypeChecker] NFC: Add more property wrapper tests 2022-08-26 12:25:22 -07:00
Arnold Schwaighofer
f295cbee19 IRGen: Fix shift amount in typelayout lowering of mulipayload enums to bits
Transfer the fix in #42131 to the typelayout lowering code. Noticed as part of
investigating the fix for #60590.
2022-08-17 14:33:52 -07:00
Nate Chandler
304013683c [SILGen] Precompute "returned" completion handler indices.
When generating the completion handler that is passed to ObjC methods
that are being called as async Swift functions, the parameters taken by
the generated completion handler are matched up with the values that are
returned from the async function.

Previously, this process was done by starting at the index into the list
of values expected to be returned, adding 1 if the index matched first
the error index and second the flag index, and finally adding 1 to
account for the fact that the initial parameter to the completion
handler is the block_storage parameter.

That strategy was problematic: it failed to increment indices
appropriately because it did not skip past the block_storage parameter
to begin with; it also failed to increment indices appropriately in
certain cases where the flag and error parameters appeared in an
unexpected order (flag first, then error).

Here, the process is made more robust.  Now, the indices which
correspond to the block_storage, flag, and error parameters are filtered
out to begin with.  The remaining indices can then be indexed into
using the index into the result tuple (or 0 if the result is not a
tuple).

rdar://80847020
2021-07-20 14:32:32 -07:00
Arnold Schwaighofer
24925db1f5 Use a async function pointer for default async protocol witness implemenations
Protocol witness table entries of async functions need to be async
function pointers.

rdar://77474699
2021-05-21 13:50:10 -07:00
Slava Pestov
94287ea6a9 AST: Fix bad interaction between vtable layout, access control and -enable-testing
Swift allows a method override to be more visible than the base method.

In practice, this means that since it might be possible for client
code to see the override but not the base method, we have to take
extra care when emitting the override.

Specifically, the override always receives a new vtable entry, and
a vtable thunk is emitted in place of the base method's vtable entry
which re-dispatches via the override's vtable entry.

This allows client code to further override the method without any
knowledge of the base method's vtable entry, which may be inaccessible
to the client.

In order for the above to work, three places in the code perform
co-ordinated checks:

- needsNewVTableEntry() determines whether the override is more
  visible than the base, in which case it receives a new vtable
  entry

- SILGenModule::emitVTableMethod() performs the same check in order
  to emit the re-dispatching vtable thunk in place of the base
  method's entry

- in the client, SILVTableVisitor then skips the base method's
  vtable entry entirely when emitting the derived class, since no
  thunk is to be emitted.

The problem was that the first two used effective access (where
internal declarations become public with -enable-testing), while
the last check used formal access. As a result, it was possible
for the method override vtable entry to never be emitted in the
client.

Consistently using either effective access or formal access would
fix the problem. I fixed the first two to rely on formal access;
the reason is that using effective access makes vtable layout
depend on whether the library was built with -enable-testing or
not, which is undesirable since we do not want -enable-testing to
impact the ABI, even for non-resilient frameworks.

Fixes rdar://problem/74108928.
2021-02-09 23:35:14 -05:00
Ellis Hoag
3aa081c56e [IRGen] Call objc_direct methods correctly 2020-10-23 11:54:07 -05:00
Yuta Saito
d6cddaabb5 [LTO] Support LLVM LTO for driver
This commit adds LTO support for handling linker options and LLVM BC
emission. Even for ELF, swift-autolink-extract is unnecessary because
linker options are embeded in LLVM BC content when LTO.
2020-07-31 10:17:59 +09:00
Mishal Shah
10dda582d6 [Apple Silicon] Update tests for no macOS target triple canonicalization
LLVM no longer canonicalizes target triples for maOS versions. Update
tests to account for this.
2020-07-02 19:30:01 -07:00
Slava Pestov
1851630e81 IRGen: Fix crash with empty-sized field in a class with resilient ancestry
The problem was that HasObjCAncestry was not getting set if
HasResilientAncestry was true, and thus emitFieldOffsetGlobals() was
marking the field offset as const even though the Objective-C
runtime might slide it.

Fixes <rdar://problem/48031465>.
2020-04-27 19:41:42 -04:00
Slava Pestov
23cac673ca IRGen: Enable dynamic replacement with library evolution
It looks like the only thing that fails is the linkage computation
for the dynamic replacement key of class methods. Even though
methods have hidden linkage to prevent them from being directly
referenced from outside a resilient module, we need to ensure
the dynamic replacement key is visible.

Fixes <rdar://problem/58457716>.
2020-04-10 22:53:36 -04:00
Doug Gregor
def86ce402 Revert "[irgen] Force emission of objc class refs for non-foreign clang objc classes whose metadata we use."
This reverts commit 8247525471. While
correct, it has uncovered several issues in existing code bases that
need to be sorted out before we can land it again.
Fixes rdar://problem/57846390.
2020-01-11 21:46:42 -08:00
Robert Widmann
b8779f7df7 Fix getDirectlyInheritedNominalTypeDecls
getDirectlyInheritedNominalTypeDecls looks for inherited protocols in two places: the actual inheritance clause of a declaration and the trailing where clause.  This works fine for normal declarations, but deserialized protocols that have Self constraints have no trailing where clause and appear to have no super-protocol bounds.  This means clients can potentially disagree about the structure of the protocol, and any symbols derived from it.

The test case demonstrates this problem directly: We build a hollowed-out SwiftUI preview provider then try to dynamically replace a requirement in a Self-constrained protocol extension.  The SwiftUI module sees the where clause, but when we go to deserialize the module in the "Preview" the protocol extension sees the wrong inheritance bounds and mis-mangles the call to Self.view(for:ofType).

The fix is to ask the requirement signature for Self requirements that would normally appear on a trailing where clause.

Resolves rdar://57150777
2019-12-03 17:01:57 -08:00
Michael Gottesman
8247525471 [irgen] Force emission of objc class refs for non-foreign clang objc classes whose metadata we use.
Today in far more cases we are using mangled strings to look up metadata at
runtime. If we do this for an objc class but for whatever reason we do not have
any other references to the class, the static linker will fail to link in the
relevant framework. The reason why this happens is that autolinking is treated
by the static linker as a hint that a framework may be needed rather than as a
"one must link against the framework". If there aren't any undefined symbols
needed by the app from that framework, the linker just will ignore the hint. Of
course this then causes the class lookup to fail at runtime when we use our
mangled name to try to lookup the class.

I included an Interpreter test as well as IRGen tests to make sure that we do
not regress here in the future.

NOTE: The test modifications here are due to my moving the ObjCClasses framework
out of ./test/Interpreters/Inputs => test/Inputs since I am using it in the
IRGen test along side the interpreter test.

rdar://56136123
2019-11-21 16:03:54 -08:00
Arnold Schwaighofer
7acabfe1cf IRGen: We need to emit metadata for types that are emitted with shared linkage
Otherwise one TU could only require the type descriptor without metadata
and another TU could require metadata and type descriptor. Whether the
metadata access function is available would then depend on the linking
order of the two TUs.

rdar://56929811
2019-11-11 10:00:17 -08:00
Mike Ash
93128d8fea [Runtime] Add missing FakeUnavailableSwiftDylib.swift file. 2019-08-14 15:01:58 -04:00
Joe Groff
f9e5de9371 IRGen: Reenable caching opaque type metadata accessors.
Dynamic replacement can only really get away with replacing opaque return types if a function's
opaque type has never been instantiated in the first place. Meanwhile, repeatedly instantiating
the metadata is too slow for many clients to tolerate. Fixes rdar://problem/53213600.
2019-07-17 20:15:09 -07:00
Arnold Schwaighofer
b233ca78c6 Int64 in more places 2019-07-12 18:05:53 -07:00
Arnold Schwaighofer
4300a589dc Fix test/Interpreter/dynamic_replacement_opaque_result.swift
rdar://53029978
2019-07-12 17:20:57 -07:00
Stephen Canon
ca1e808bde Replace all 9999 availability in non-stdlib tests. (#26109)
Replace all 9999 availability in non-stdlib tests with the appropriate platform availability.
2019-07-12 14:48:37 -04:00
Slava Pestov
cea8a6d6dc Split up test/IRGen/jit_metadata_strategy.swift and fix the REQUIRES: line 2019-07-08 15:08:47 -04:00
Slava Pestov
e2d660f148 SILGen: Fix generated vtable thunk when a final override is more visible than the base
Don't re-dispatch to the override's vtable slot if the override
is final; there's no vtable slot and this will result in an
infinite loop.

Fixes <rdar://problem/52006394>.
2019-06-21 22:56:48 -04:00
Slava Pestov
a31248997c SILGen: Correctly emit vtables when an override is more visible than the base
If an override B.f() is more visible than a base method A.f(), it is
possible that an override C.f() of B.f() cannot see the original method
A.f().

In this case, we would encounter linker errors if we referenced the
method descriptor or method dispatch thunk for A.f().

Make this work by treating B.f() as the least derived method in this
case, and ensuring that the vtable thunk for B.f() dispatches through
the vtable again.

Fixes <rdar://problem/48330571>, <https://bugs.swift.org/browse/SR-10648>.
2019-06-01 00:08:05 -04:00
Arnold Schwaighofer
7e646847c7 SILGen: Add an option to disable the previous implementation inside of dynamic replacement thunks
@_dynamicReplacement(for: selfRec(x: acc:))
  func selfRec_r(x: Int, acc: Int) -> Int {
    if x <= 0 {
      return acc
    }
    // Normally, this will call selfRec(x: acc:)'s implementation.
    // With the option, this will call to selfRec_r(x: acc:).
    return selfRec(x: x - 1, acc: acc + 1)
  }

rdar://51229650
2019-05-29 11:31:27 -07:00
Arnold Schwaighofer
b127aac1ce Merge pull request #24781 from aschwaighofer/fix_some_type_dynamic_replacement
Fix dynamic replacement of some type when used with associated types
2019-05-23 16:36:32 -07:00
Joe Groff
3c0732ab14 Add regression test for SR-10264 2019-05-22 15:14:03 -07:00
Arnold Schwaighofer
5c3a4d329b Fix dynamic replacement of some type when used with associated types
rdar://50638228
2019-05-18 10:34:52 -07:00
Joe Groff
cec9e9e33a Opaque types require a newer Swift runtime.
Check the availability of decls that declare an opaque return type to ensure they deploy to a
runtime that supports opaque types.

rdar://problem/50731151
2019-05-15 11:39:53 -07:00
Arnold Schwaighofer
a0387eea40 Opaque result types: Dynamic replacement fixes for computed properties 2019-04-22 08:32:43 -07:00
Arnold Schwaighofer
84c7b77d02 Make opaque type descriptors dynamically replaceable
This is to support dynamic function replacement of functions with opaque
result type.

This approach requires that all state is thrown away (that could contain the
old returned type for an opaque type) between replacements.

rdar://48887938
2019-04-22 07:31:07 -07:00
Arnold Schwaighofer
1b863d6787 Allow final on dynamic members
Dynamic is about dynamically replacing a method implementiation not
overriding.

rdar://49535048
2019-04-04 07:26:43 -07:00
Arnold Schwaighofer
35ca0e3423 Add support for dynamic replacement of didSet/willSet
The observer in a dynamic replacement of variables with a observer will
provide the dynamic replacement for the original.

var original : Int = 0 {
  didSet {
    print("original")
  }
}

@_dynamicReplacement(for: original)
var replacement : Int = 0 {
  didSet {
    print("replacement")
  }
}

rdar://48518788
2019-03-15 16:30:03 -07:00
Arnold Schwaighofer
8d9b9f328b SILGen: Fix the logic of dynamic replacements for class constructors
To correctly call designated super class initializers the designated
intializer (and not the allocator) is dynamically replaceable.
Convenience allocators are dynamically replaceable as before.
2019-02-22 10:15:06 -08:00
Arnold Schwaighofer
8394fc525e DynamicReplacement: Don't fail when a library is closed and reloaded
rdar://47560273
2019-01-25 13:50:27 -08:00
Arnold Schwaighofer
24b8766b31 Fix test 2018-11-15 10:56:08 -08:00
Arnold Schwaighofer
edd4f2ca6a Don't implicitly add dynamic to stored properties
This can introduce an exclusivity check failure.
2018-11-15 09:50:00 -08:00
Arnold Schwaighofer
b033d1b443 Calling the previous implementation does not work for global vars yet 2018-11-14 08:49:00 -08:00
Arnold Schwaighofer
081bb95bee Synthesize accessors for dynamic global variables 2018-11-14 07:57:45 -08:00
Arnold Schwaighofer
28da6b1075 Sema: Don't add dynamic to dynamic replacement decls
They can't be dynamic.

Add test for enable-implicit-dynamic flag.
2018-11-13 09:36:54 -08:00
Arnold Schwaighofer
fb7b223ba2 Add support to modify chaining behavior of dynamic replacements
Default to not chain dynamic replacements: Only one replacement and the
original implementation are active.
2018-11-09 13:17:09 -08:00
Arnold Schwaighofer
152e8db8bb IRGen and runtime implementation for dynamic replacements 2018-11-06 09:58:36 -08:00
Michael Gottesman
dd8edef2d5 [typelowering] Look through 1 level of optionality when determining if a value has a NewType representation.
This is necessary to ensure that we autorelease such values in objc thunks.
Previously, we were returning the value as unowned, leaking it. I added a test
to interpreter that will make sure in the future we do not leak like this
again.

rdar://45543138
2018-10-25 18:52:31 -07:00