When constructing the metadata for a type Gen<T : Super>
where Super is a superclass constraint, the generic argument K at which
the metadata for Gen is being instantiated is verified to be a subclass
of Super via _checkGenericRequirements.
Previously, that check was done using swift_dynamicCastMetatype. That
worked for the most part but provided an incorrect answer if the
metadata for K was not yet complete. These classes are incomplete more
often thanks to __swift_instantiateConcreteTypeFromMangledNameAbstract.
That issue occurred concretely in the following case:
Framework with Library Evolution enabled:
open class Super { ... }
public struct Gen<T : Super> {
}
Target in a different resilience domain from that framework:
class Sub : Super {
var gen: Gen<Sub>?
}
Here, the mechanism for checking whether the generic argument K at which
the metadata for Gen is being instantiated handles the case where K's
metadata is incomplete. At worst, every superclass name from super(K)
up to Super are demangled to instantiate metadata. A number of faster
paths are included as well.
rdar://problem/60790020
In preparation for the prespecialization of metadata for generic
classes, make checkMetadataState always return that the state of
prespecialized class metadata is complete, as is done for generic
structs and enums already.
Extracted implementation of SpecializedGenericStructMetadataBuilder into
SpecializedGenericNominalMetadataBuilderBase, a CRTP with a template
template argument for the CRTP superclass and a template argument for
the implementation. That new type is now subclassed by
SpecializedGenericStructMetadataBuilder. Additionally, this new type is
also subclassed by the newly added SpecializedGenericEnumMetadataBuilder
which is responsible for build the prespecialization of generic enum
metadata.
rdar://problem/56960887
Due to some unfortunate interplay between clang and libstdc++, clang was
not able to correctly identify to alignment of PoolRange and
SideTableRefCountBits, causing it to emit library calls instead of
inlining atomic operations. This was fixed by adding the appropriate
alignment to those types. In addition to that the march for the Linux
target was set to 'core2', which is the earliest architecture to support
cx16, which is necessary for the atomic operations on PoolRange.
Added a new flag to the GenericMetadataPatternFlags flagset for whether
the metadata has a set of flags at its tail. When that flag is set,
there will be an extra uint64_t flagset at the end of the metadata. For
struct metadata, the type of that flagset will be
StructMetadataTrailingFlags. The first flag in that trailing flagset
indicates whether the metadata was statically specialized. The second
flag in that trailing flagset indicates whether the metadata is
statically canonical.
When verifying the metadata cache, a check is done for whether the
metadata was statically specialized and whether it was known to be
canonical statically. If so, verification is skipped. Skipping it is
necessary because the known-canonical statically specialized metadata
will not be in the cache. In that case, the canonical statically
specialized metadata will be returned from the metadata accessor and
never be cached.
SR-5289: Teach Mirror how to inspect weak, unowned, and unmanaged refs
Correctly reflect weak, unowned, and unmanaged references
to both Swift and Obj-C types (including existential references to
such types) that occur in both Swift class objects and in Swift
structs.
This includes the specific reported case (unowned reference to an
Obj-C object) and several related ones.
Related changes in this PR:
* Tweak internal bitmap used for tracking ownership modifiers
to reject unsupported combinations.
* Move FieldType into ReflectionMirror.mm
FieldType is really just an internal implementation detail
of this one source file, so it does not belong in an ABI header.
* Use TypeReferenceOwnership directly to track field ownership
This avoids bitwise copying of properties and localizes some
of the knowledge about reference ownership
* Generate a top-level "copyFieldContents" from ReferenceStorage.def
Adding new ownership types to ReferenceStorage.def will now
automatically produce calls to `copy*FieldContents` - failure
to provide a suitable implementation will fail the build.
* Add `deallocateBoxForExistentialIn` to match `allocateBoxForExistentialIn`
Caveat: The unit tests are not as strict as I'd like. Attempting to make them
so ran afoul of otherwise-unrelated bugs in dynamic casting.
* SR-5289: Support reflecting weak, unowned, and unmanaged refs
This refactors how we handle reference ownership
when reflecting fields of struct and class objects.
There are now explicit paths for each type of reference
and some simple exhaustiveness checks to fail the build
if a new reference type is added in the future without
updating this logic.
This removes it from the AST and largely replaces it with AnyObject
at the SIL and IRGen layers. Some notes:
- Reflection still uses the notion of "unknown object" to mean an
object with unknown refcounting. There's no real reason to make
this different from AnyObject (an existential containing a
single object with unknown refcounting), but this way nothing
changes for clients of Reflection, and it's consistent with how
native objects are represented.
- The value witness table and reflection descriptor for AnyObject
use the mangling "BO" instead of "yXl".
- The demangler and remangler continue to support "BO" because it's
still in use as a type encoding, even if it's not an AST-level
Type anymore.
- Type-based alias analysis for Builtin.UnknownObject was incorrect,
so it's a good thing we weren't using it.
- Same with enum layout. (This one assumed UnknownObject never
referred to an Objective-C tagged pointer. That certainly wasn't how
we were using it!)
This makes for a cleaner and less implicit-context-heavy API, and makes it easier for symbolic
reference resolvers to do context-dependent things (like map the in-memory base address back to a
remote address in MetadataReader).
The memcpy in the type layout verifier was not correct for big-
endian systems. While we are here change 'long long' to a fixed
width unsigned type (uint64_t). It doesn't really make sense to
print the value as a signed number since we have zero extended
it from its original bit width using the memcpy.
Unfortunately, `std::atomic` in msvcprt as of 14.21.27702 is broken for
double-width atomics on ARM64. This has been reported to Microsoft and
is going to be fixed in VC++ 2019u3. For the time being, add a partial
template specialisation for the two double-word sized types temporarily
as a workaround. This allows the standard library build to get further.
When building without assertions, the variable will be unreferenced on
non-ObjC runtimes. Sink the evaluation into the assertion and move the
declaration into the ObjC runtime case.
Build a static archive that can be linked into executables and take advantage of the Swift runtime's
hooking mechanism to work around the issue Doug fixed in https://github.com/apple/swift/pull/24759.
The Swift 5.0 version of swift_conformsToProtocol would return a false negative in some cases where
a subclass conforms using an inherited conformance, so work around this by successively retrying
the original implementation up the superclass chain to try to find a match.
This will allow us to emit class stubs unconditionally, rather than
checking the -enable-resilient-objc-class-stubs flag.
Part of <rdar://problem/49090631>.
This adds a new tail-allocated field to class context descriptors storing
a pointer to an Objective-C class stub.
When the stub is present, we use the new _objc_realizeClassFromSwift()
entry point to realize the class instead of calling objc_readClassPair().
This should attach categories to the realized class, if they were emitted
to reference the stub.
Extract common code from the old and new remangler into a common base class.
This lets the old remangler benefit from the changes I did recently in the new remangler.
This is needed for Windows which does not support cross-module data
references without indirection. By lazy initializing the data, we can
indirect through the IAT for the data pointer and fill in the parent
pointer.
Recent Swift uses 2 as the is-Swift bit when running on newer versions, and 1 on older versions. Since it's difficult or impossible to know what we'll be running on at build time, make the selection at runtime.
Instead of capturing SubstGenericParametersFromMetadata and SubstGenericParametersFromWrittenArgs by value, capture by reference.
This avoids those instances to be copied and thus avoids a lot of mallocs.
SR-10028
rdar://problem/48575729