Commit Graph

19 Commits

Author SHA1 Message Date
Konrad `ktoso` Malawski
7d1ce789ad Revert "Revert "Isolated synchronous deinit"" 2024-09-17 17:35:38 +09:00
Alex Hoppen
c5aa49ba64 Revert "Isolated synchronous deinit" 2024-09-03 18:11:26 -07:00
Mykola Pokhylets
62dbc6c966 Fixed some tests. Using extract_executor SIL instruction instead of custom code. 2024-07-11 13:09:06 +02:00
Jordan Rose
a52fac4470 [Serialization] Store whether an override depends on its base for ABI (#27784)
In some circumstances, a Swift declaration in module A will depend on
another declaration (usually from Objective-C) that can't be loaded,
for whatever reason. If the Swift declaration is *overriding* the
missing declaration, this can present a problem, because the way
methods are dispatched in Swift can depend on knowing the original
class that introduced the method. However, if the compiler can prove
that the override can still be safely invoked/used in all cases, it
doesn't need to worry about the overridden declaration being missing.

This is especially relevant for property accessors, because there's
currently no logic to recover from a property being successfully
deserialized and then finding out that an accessor couldn't be.

The decision of whether or not an override can be safely invoked
without knowledge of the base method is something to be cautious
about---a mistaken analysis would effectively be a miscompile. So up
until now, this was limited to one case: when a method is known to be
`@objc dynamic`, i.e. always dispatched through objc_msgSend. (Even
this may become questionable if we have first-class method references,
like we do for key paths.) This worked particularly well because the
compiler infers 'dynamic' for any overload of an imported Objective-C
method or accessor, in case it imports differently in a different
-swift-version and a client ends up subclassing it.

However...that inference does not apply if the class is final, because
then there are no subclasses to worry about.

This commit changes the test to be more careful: if the /missing/
declaration was `@objc dynamic`, we know that it can't affect ABI,
because either the override is properly `@objc dynamic` as well, or
the override has introduced its own calling ABI (in practice, a direct
call for final methods) that doesn't depend on the superclass. Again,
this isn't 100% correct in the presence of first-class methods, but it
does fix the issue in practice where a property accessor in a parent
class goes missing. And since Objective-C allows adding property
setters separately from the original property declaration, that's
something that can happen even under normal circumstances. Sadly.

This approach could probably be extended to constructors as well. I'm
a little more cautious about throwing vars and subscripts into the mix
because of the presence of key paths, which do allow identity-based
comparison of overrides and bases.

rdar://problem/56388950
2019-10-21 15:53:25 -07:00
Slava Pestov
1ee2db4520 AST: Accessors no longer appear as members of their parent DeclContext
Accessors logically belong to their storage and can be synthesized
on the fly, so removing them from the members list eliminates one
source of mutability (but doesn't eliminate it; there are also
witnesses for derived conformances, and implicit constructors).

Since a few ASTWalker implementations break in non-trivial ways when
the traversal is changed to visit accessors as children of the storage
rather than peers, I hacked up the ASTWalker to optionally preserve
the old traversal order for now. This is ugly and needs to be cleaned up,
but I want to avoid breaking _too_ much with this commit.
2019-07-30 15:56:00 -04:00
Slava Pestov
d3cd9c2d7b Serialization: Track vtable slots for VarDecl and SubscriptDecl
Once accessors are no longer listed as members of their parent context,
a failure to deserialize a VarDecl or SubscriptDecl needs to create a
MissingMemberDecl with the total number of vtable entries expected for
all of the accessors of the storage.

Note that until the accessor change actually lands, we always compute
the expected number of vtable entries as 0.
2019-07-30 15:44:53 -04:00
Jordan Rose
2d3872a076 [Serialization] If an override is dynamic, missing the base decl is OK
...specifically `@objc dynamic`, that is. This is one case where we
/know/ that the override does not depend on the base in any way---any
attributes have already been propagated down, and there's no vtable
entry. This is especially important for properties, which have no
recovery if their accessors can't be deserialized.

rdar://50827914
2019-06-18 13:46:49 -07:00
Jordan Rose
a69656f178 [Serialization] Don't crash if we can't get the type for an XREF (#12914)
If we can't resolve a cross-reference unambiguously, we're supposed to
produce an llvm::Error and let the calling code handle it. However, if
we couldn't even resolve the /type/ of the cross-reference, we would
just crash. Follow the supported error path in that case too -- in
many cases the error can just propagate upwards to something that can
handle it.

rdar://problem/34821187, plus an extra test case from
rdar://problem/35157494. (The latter will be fixed better later, but
meanwhile let's not regress on the crashing part.)
2017-11-15 09:32:48 -08:00
Robert Widmann
71bf312a25 Migrate the rest of the tests to %empty-directory 2017-06-04 11:08:39 -07:00
Jordan Rose
e0c248c932 Turn on deserialization recovery by default. (#9486)
I'm still leaving a -disable-deserialization-recovery flag in there
just in case.
2017-05-11 08:47:59 -07:00
Jordan Rose
4cdb597b23 Rename VTablePlaceholderDecl to MissingMemberDecl.
As such, we no longer insert two placeholders for initializers that
need two vtable slots; instead we record that in the
MissingMemberDecl. I can see MissingMemberDecl growing to be something
we'd actually show to users, that can be used for other kinds of
declarations that don't have vtable entries, but for now I'm not going
to worry about any of that.
2017-05-10 11:55:55 -06:00
Jordan Rose
47cddb1321 [Serialization] Generate VTablePlaceholder decls for classes.
They still aren't hooked up to anything yet, but now we can check that
they're showing up where we expect them.
2017-05-10 11:55:54 -06:00
Jordan Rose
5344d16039 [Serialization] Make sure grandchild overrides can be dropped too.
If a base method's not available, we already drop the overridding
method. Make sure this works even when the base method is itself
an override that failed to load.
2017-04-27 18:30:35 -07:00
Jordan Rose
abdaaefe29 [Serialization] Drop overriding initializers with missing bases.
This is the same as the last few commits, but with the additional
complication of designated initializers affecting other behavior
around the type. In particular, convenience initializers cannot be
invoked on subclasses if the designated initializers are not all
present on the subclass. If a designated initializer is dropped, it's
not possible to satisfy that.

It would be nice to do better here, since a class's initializers are
mostly independent of the superclass's initializers. Unfortunately, it
still affects whether /this/ class can inherit convenience
initializers, as well as vtable layout. This is conservative, at
least.
2017-04-24 11:53:54 -07:00
Jordan Rose
d0a9ec509e [Serialization] Drop overriding properties with missing bases.
Like the previous commit, but with added trickiness because we also
serialize the form of the PatternBindingDecl a property came from.
Make getPattern handle a failure in the simple case that overrides
use, and pass that up to the PatternBindingDecl initialization. (This
can result in zero-element PatternBindingDecls, but that's fine.)

'getPattern' is also a change from 'maybeGetPattern', but every caller
knows how many patterns it expects, so accomodating the "maybe" case
is no longer important.
2017-04-11 10:37:30 -07:00
Jordan Rose
970f95930c [Serialization] Drop overriding subscripts with missing bases.
This only handles cases where a subscript disappears wholesale;
if one becomes read-only (for whatever terrible reason) the
compiler will still crash.
2017-04-11 10:37:30 -07:00
Jordan Rose
a2e0e27624 [test] Add some more tests for 73d4526.
There's still nothing really complicated going on here, such as an
override that previously satisfied a protocol conformance.
2017-04-10 16:38:59 -07:00
Jordan Rose
7e8d642e8e [Serialization] When crashing, note if mix-and-match may be to blame.
That is, a Swift 3 target imported into a Swift 4 context or vice
versa. This requires serializing the compatibility mode explicitly,
instead of including it in the textual version string that's only
for debugging.
2017-04-10 16:38:58 -07:00
Jordan Rose
73d4526943 [Serialization] Drop overriding methods if the base is missing.
Proof-of-concept for this sort of recovery. In the real world, it's
more likely that this will happen due to differences between Swift 3
and Swift 4, rather than changes in what macros are defined, but the
latter can still happen when debugging.

There's a lot to do here to consider this production-ready. There are
no generics involved and no potential circular references, and the
/rest/ of the compiler isn't prepared for this either. But it's cool
to see it working!

Actually recovering is hidden behind the new
-enable-experimental-deserialization-recovery option; without it the
compiler will continue to eagerly abort.
2017-04-05 18:32:08 -07:00