This changes code generation a bit, because now the conditional
state bitmap uses a bit to track if the 'self' box was stored,
not if the 'self' value was consumed. In some cases, this
eliminates an extra bit, in other places it introduces an
extra bit, but it really doesn't matter because LLVM will
optimize this bit manipulation easily.
Previously protocol extension initializers which called 'self.init' were
considered 'delegating', and ones that assign to 'self' were considered
'root'.
Both have the same SIL lowering so the distinction is not useful, and
removing it simplifies some code.
This allows, for example, an initializer to conditionally assign
to self or call self.init, along different control flow paths.
It also means that it is legal to call self.init() multiple times
in a value type initializer, but this... is fine. The old 'self'
is destroyed.
Fixes <rdar://problem/33137910>.
This changes layout of the parameter metadata from single tuple record
(in case of materializable type) to N records each corresponding to
invididual function parameter, where functions with no parameters
`() -> Void` get 0 records allocated.
Consider the following code:
protocol P {
func foo<A>(_: A)
}
extension P {
func foo<A>(_: A) {}
}
class C<T> : P {}
Before, the witness thunk for [C : P].foo() had the generic signature
<T, A>, and the witness P.foo() was called with a substitution
Self := C<T>.
This is incorrect because the caller might be using a subclass of C
as the 'Self' type, but this was being erased.
Now, the witness thunk for [C : P].foo() has the generic signature
<X : C<T>, T, A>, and the witness P.foo() is called with the
substitution Self := X.
Fixes <rdar://problem/33690383>, <https://bugs.swift.org/browse/SR-617>.
Consider the following code:
protocol P {
func foo<A>(_: A)
}
extension P {
func foo<A>(_: A) {}
}
class C<T> : P {}
Before, the witness thunk for [C : P].foo() had the generic signature
<T, A>, and the witness P.foo() was called with a substitution
Self := C<T>.
This is incorrect because the caller might be using a subclass of C
as the 'Self' type, but this was being erased.
Now, the witness thunk for [C : P].foo() has the generic signature
<X : C<T>, T, A>, and the witness P.foo() is called with the
substitution Self := X.
Fixes <rdar://problem/33690383>, <https://bugs.swift.org/browse/SR-617>.
A lazy property setter stores a value to the underlying storage
of the lazy property. The underlying storage is private, and it
is not proper for a public transparent function body to reference
a private member.
In practice, this only failed if the private member had a
non-constant offset, which only occurs with subclasses of @objc
classes, and resilient classes.
For @objc classes we already had a workaround where no accessors
for stored properties are ever transparent. I put this in to fix
this very issue with lazy properties, but now I realize it was
the wrong workaround, because we still had this problem with
resilient classes.
Note that I'm keeping the logic which made @objc accessors
non-transparent in place, because there's a good chance we will
decide that field offset globals should always be private.
Also, to make this issue reproducible in the test, I changed the
resilience execution tests to build the resilient library as a
dylib and link against that instead of just linking .o files
together. This is because .o files can see each other's internal
symbols, so I was not able to reproduce the original failure
this way. I went ahead and updated the other resilient tests to
do this as well. Also, each test now builds in WMO and non-WMO
mode, to exercise different SIL linking behavior. Again, the
WMO variant was needed to reproduce the issue fixed by this
commit, because without WMO we currently discard serialized SIL,
so no cross-module inlining of the lazy property setter was
taking place.
A protocol extension initializer creates a new instance of the
static type of Self at the call site.
However a convenience initializer in a class is expected to
initialize an instance of the dynamic type of the 'self' value,
because convenience initializers can be inherited by subclasses.
This means that when a convenience initializer delegates to a
protocol extension initializer, we have to substitute the
'Self' type in the protocol extension generic signature with
the DynamicSelfType, and not the static type.
Since the substitution is formed from the type of the 'self'
parameter in the class convenience initializer, the solution is
to change the type of 'self' in a class convenience initializer
to DynamicSelfType, just like we do for methods that return
'Self'.
This fixes cases where we allowed code to type check that
should not type check (if the protocol extension initializer
has 'Self' in contravariant position, and we pass in an
instance of the static type).
It also fixes a miscompile with valid code -- if the protocol
extension initializer was implemented by calling 'Self()',
it would again use the static type and not the dynamic type.
Note that the SILGen change is necessary because Sema now creates
CovariantReturnExprs that convert a static class type to
DynamicSelfType, but the latter lowers to the former at the
SIL level, so we have to peephole away unnecessary unchecked_ref_cast
instructions in this case.
Because this change breaks source compatibility, it is guarded
by a '-swift-version 5' check.
On 32bit platforms there are 7 bits reserved for the unowned retain count. This
makes overflow a likely scenario. Implement overflow into the side table.
rdar://33495003
LLVM r307372 makes it so that the current running macOS version is
always chosen as the default target. It's unclear whether that's the
behavior we want or not; deciding that is tracked by
rdar://problem/29948658. For now, just disable that part of the test.
Due to a serendipitous confluence of interesting behaviors,
Swift 3 allowed you to define a lazy property with an IUO
type, and setting the property to nil would 'reset' it,
re-evaluating the lazy getter the next time the property
was accessed.
This was not intended behavior and it no longer works,
so add a test that it no longer works.
Fixes <rdar://problem/32687168> and
<https://bugs.swift.org/browse/SR-5172>.
* IRGen: Use LLVM's alloc size to compute padding between types
We need to subtract alignment padding when doing type layout in terms of llvm types
rdar://32618125
SR-5137
Logs a warning the first time a problematic class is archived or
unarchived. We expect people to actually fix these issues, so the
performance of the warning isn't too important.
Sample output:
[timestamp] Attempting to archive Swift class '_Test.Outer.ArchivedThenUnarchived', which does not have a stable runtime name.
[timestamp] Use the 'objc' attribute to ensure that the runtime name will not change: "@objc(_TtCC5_Test5Outer22ArchivedThenUnarchived)"
[timestamp] If there are no existing archives containing this class, you can choose a unique, prefixed name instead: "@objc(ABCArchivedThenUnarchived)"
Finishes rdar://problem/32414508
* IRGen: EmptyBoxType's representation cannot be nil because of a conflict with extra inhabitant assumption in indirect enums
We map nil to the .None case of Optional. Instead use a singleton object.
SR-5148
rdar://32618580
This function checks if a mangled class name is going to be written into an NSArchive.
If yes, a warning should be printed and the return value should indicate that.
TODO: print the actual warning
rdar://problem/32414508
This time, the warnings only fire when the class in question directly
conforms to NSCoding. This avoids warning on cases where the user has
subclassed something like, oh, UIViewController, and has no intention
of writing it to a persistent file.
This also removes the warning for generic classes that conform to
NSCoding, for simplicity's sake. That means
'@NSKeyedArchiverEncodeNonGenericSubclassesOnly' is also being
removed.
Actually archiving a class with an unstable mangled name is still
considered problematic, but the compiler shouldn't emit diagnostics
unless it can be sure they are relevant.
rdar://problem/32314195
This is accomplished by recognizing this specific situation and
replacing the 'objc' attribute with a hidden '_objcRuntimeName'
attribute. This /only/ applies to classes that are themselves
non-generic (including any enclosing generic context) but that have
generic ancestry, and thus cannot be exposed directly to Objective-C.
This commit also eliminates '@NSKeyedArchiverClassName'. It was
decided that the distinction between '@NSKeyedArchiverClassName' and
'@objc' was too subtle to be worth explaining to developers, and that
any case where you'd use '@NSKeyedArchiverClassName' was already a
place where the ObjC name wasn't visible at compile time.
This commit does not update diagnostics to reflect this change; we're
going to change them anyway.
rdar://problem/32414557