Commit Graph

200 Commits

Author SHA1 Message Date
Mike Ash
b86fe88c43 [Runtime] Fix key argument indexing when checking invertible protocols.
Track the key argument index separately from the generic parameter index when performing the invertible protocol checking in _checkGenericRequirements. This keeps the indexing correct when a non-key argument is followed by a key argument.

rdar://128774651
2024-06-11 12:39:23 -04:00
Doug Gregor
ae01d20428 Runtime checking for associated types conforming to invertible protocols
Emit metadata for runtime checks of conformances of associated types to
invertible protocols, e.g., `T.Assoc: Copyable`. This allows us to
correctly handle, e.g., dynamic casting involving conditional
conformances that have such constraints.

The model we use here is to emit an invertible-protocol constraint
that leaves only the specific bit clear in the invertible protocol
set.
2024-04-02 16:42:16 -07:00
Doug Gregor
b84f8ab080 Rename "suppressible protocols" to "invertible protocols".
We've decided to use the "invertible protocols" terminology throughout
the runtime and compiler, so move over to that terminology
consistently.
2024-03-29 11:31:48 -07:00
Doug Gregor
cd20dbafbf [Runtime] Don't check suppressible protocols for non-key generic arguments 2024-03-26 21:33:53 -07:00
Doug Gregor
af38d88ba3 Fix typos spotted by code review, thank you! 2024-03-22 08:28:45 -07:00
Doug Gregor
11774e5d17 [Runtime] Check function types against suppressible protocols
Form a set of suppressed protocols for a function type based on
the extended flags (where future compilers can start recording
suppressible protocols) and the existing "noescape" bit. Compare
that against the "ignored" suppressible protocol requirements, as we
do for other types.

This involves a behavior change if any client has managed to evade the
static checking for noescape function types, but it's unlikely that
existing code has done so (and it was unsafe anyway).
2024-03-22 07:45:50 -07:00
Doug Gregor
5b020068c5 Extend runtime checking for suppressible protocols
Add more runtime support for checking suppressible protocol requirements:
* Parameter packs now check all of the arguments appropriately
* Most structural types now implement checking (these are hard to test).
2024-03-21 19:22:28 -07:00
Doug Gregor
b167eece42 Metadata and runtime support for suppressible protocol requirements
Introduce metadata and runtime support for describing conformances to
"suppressible" protocols such as `Copyable`. The metadata changes occur
in several different places:

* Context descriptors gain a flag bit to indicate when the type itself has
  suppressed one or more suppressible protocols (e.g., it is `~Copyable`).
  When the bit is set, the context will have a trailing
  `SuppressibleProtocolSet`, a 16-bit bitfield that records one bit for
  each suppressed protocol. Types with no suppressed conformances will
  leave the bit unset (so the metadata is unchanged), and older runtimes
  don't look at the bit, so they will ignore the extra data.
* Generic context descriptors gain a flag bit to indicate when the type
  has conditional conformances to suppressible protocols. When set,
  there will be trailing metadata containing another
  `SuppressibleProtocolSet` (a subset of the one in the main context
  descriptor) indicating which suppressible protocols have conditional
  conformances, followed by the actual lists of generic requirements
  for each of the conditional conformances. Again, if there are no
  conditional conformances to suppressible protocols, the bit won't be
  set. Old runtimes ignore the bit and any trailing metadata.
* Generic requirements get a new "kind", which provides an ignored
  protocol set (another `SuppressibleProtocolSet`) stating which
  suppressible protocols should *not* be checked for the subject type
  of the generic requirement. For example, this encodes a requirement
  like `T: ~Copyable`. These generic requirements can occur anywhere
  that there is a generic requirement list, e.g., conditional
  conformances and extended existentials. Older runtimes handle unknown
  generic requirement kinds by stating that the requirement isn't
  satisfied.

Extend the runtime to perform checking of the suppressible
conformances on generic arguments as part of checking generic
requirements. This checking follows the defaults of the language, which
is that every generic argument must conform to each of the suppressible
protocols unless there is an explicit generic requirement that states
which suppressible protocols to ignore. Thus, a generic parameter list
`<T, Y where T: ~Escapable>` will check that `T` is `Copyable` but
not that it is `Escapable`, and check that `U` is both `Copyable` and
`Escapable`. To implement this, we collect the ignored protocol sets
from these suppressed requirements while processing the generic
requirements, then check all of the generic arguments against any
conformances not suppressed.

Answering the actual question "does `X` conform to `Copyable`?" (for
any suppressible protocol) looks at the context descriptor metadata to
answer the question, e.g.,

1. If there is no "suppressed protocol set", then the type conforms.
This covers types that haven't suppressed any conformances, including
all types that predate noncopyable generics.
2. If the suppressed protocol set doesn't contain `Copyable`, then the
type conforms.
3. If the type is generic and has a conditional conformance to
`Copyable`, evaluate the generic requirements for that conditional
conformance to answer whether it conforms.

The procedure above handles the bits of a `SuppressibleProtocolSet`
opaquely, with no mapping down to specific protocols. Therefore, the
same implementation will work even with future suppressible protocols,
including back deployment.

The end result of this is that we can dynamically evaluate conditional
conformances to protocols that depend on conformances to suppressible
protocols.

Implements rdar://123466649.
2024-03-21 14:57:47 -07:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Allan Shortlidge
3a3a2460df NFC: Resolve -Wformat warning in ProtocolConformance.cpp. 2024-01-12 17:41:50 -08:00
Alejandro Alonso
de8233a5d6 Revert "Merge pull request #68844 from Azoy/gather-no-parameters"
This reverts commit ccaf427fc3, reversing
changes made to bf45c55530.
2023-10-10 19:36:20 -07:00
Alejandro Alonso
3ddec4fd83 Wrap _checkGenericRequirements instead for _instantiateCheckedGenericMetadata 2023-10-09 15:02:29 -07:00
Saleem Abdulrasool
da314bc7d7 runtime: silence some -Wformat warnings (NFC)
Use `z` rather than `l` for the modifier as the values are `size_t`
rather than `long`.  This fixes a bit of warning spew on Windows.
2023-08-04 08:47:23 -07:00
Mike Ash
fe7e13bba5 [Runtime][IRGen] Sign type context descriptor pointers.
Ensure that context descriptor pointers are signed in the runtime by putting the ptrauth_struct attribute on the types.

We use the new __builtin_ptrauth_struct_key/disc to conditionally apply ptrauth_struct to TrailingObjects based on the signing of the base type, so that pointers to TrailingObjects get signed when used with a context descriptor pointer.

We add new runtime entrypoints that take signed pointers where appropriate, and have the compiler emit calls to the new entrypoints when targeting a sufficiently new OS.

rdar://111480914
2023-07-07 18:10:35 -04:00
Slava Pestov
8742b1a1e2 Runtime: Fix shape requirement handling in _checkGenericRequirements()
We would say the shape requirement was always satisfied since we
incorrectly checked the left-hand side type twice.
2023-06-21 15:03:53 -04:00
Slava Pestov
3052e36f7e Runtime: Fix dynamic casts of variadic types that conditionally conform 2023-06-21 13:42:57 -04:00
Mike Ash
110f428780 [Runtime] Add tracing for section scans.
Section scans (for metadata, protocols, etc.) can be costly. This change adds tracing calls to those scans so we can more easily see how much time is spent in these scans and where they're initiated.

This adds an os_signpost implementation controlled by SWIFT_STDLIB_TRACING, and a default empty implementation for when that's disabled.

rdar://110266743
2023-06-14 12:07:44 -04:00
Slava Pestov
c50e8bb5de Runtime: Check same-type pack requirements in checkGenericPackRequirement() 2023-03-17 22:19:18 -04:00
Slava Pestov
a21b0d9749 Runtime: Check layout pack requirements in checkGenericPackRequirement() 2023-03-17 22:19:18 -04:00
Slava Pestov
d17baed985 Runtime: Check superclass pack requirements in checkGenericPackRequirement() 2023-03-17 22:19:17 -04:00
Slava Pestov
d776f71b4f Runtime: Teach checkGenericRequirements() to check same-shape and conformance pack requirements 2023-03-09 09:42:00 -05:00
Slava Pestov
2cf1241a7c Runtime: Extract checkGenericRequirement() from checkGenericRequirements() 2023-03-09 01:54:51 -05:00
Slava Pestov
32caa17b11 Runtime: Finish removing the 'extra argument' notion 2023-03-03 02:21:08 -05:00
Slava Pestov
d5b75fe7d2 Runtime: Add GenericRequirementKind::SameShape and stub out cases 2023-02-28 17:33:06 -05:00
Arnold Schwaighofer
1fa68ff82b Sign relative protocol witness tables
rdar://98583748
2023-02-20 12:29:13 -08:00
Alejandro Alonso
acb7f8efda Implement generic signature checking for PartialType.create(with:) (#63496)
Check other constraints

some more fixes
2023-02-08 10:10:58 -08:00
Arnold Schwaighofer
770648f161 Initial runtime changes to support relative protocol witness tables 2023-01-31 10:59:37 -08:00
Jonathan Grynspan
c889270a38 Remove lookupSymbol() and have all callers use SymbolInfo::lookup() instead (#62552) 2022-12-14 08:33:32 -05:00
Jonathan Grynspan
26fc627ad0 Fix a use-after-free bug on Win32 when calling lookupSymbol() (#62484) 2022-12-13 09:04:34 -05:00
Mike Ash
e15783ecd4 [Runtime] Fix concurrent lookups of types by name (again).
Fix a potential false positive if we check a class for a protocol conformance and its superclasses aren't yet instantiated.

This was partially fixed before, but we were incorrectly saying that all superclasses had been instantiated if they had been instatiated by the LAST check in conformsToProtocol. That left us open for a possible false positive in an earlier check to go unnoticed.

This change fixes it by checking for uninstantiated superclasses after each iteration over superclasses, not just the last one.

This change also makes the concurrentTypeByName test much more robust. The original test caught this bug only rarely, but the new one catches it it reliably. We now look up 1000 types per test run. Testing locally, we typically hit the race after less than 100 types.

rdar://82364236
2022-09-23 16:45:30 -04:00
Mike Ash
f2407bf0a7 [Runtime] Fix short-circuiting of shared cache conformance lookups.
We were skipping shared cache queries if the ObjC metadata or descriptor were outside the shared cache, but we need to skip only if they're both outside the shared cache. We also need to check foreign types even if the descriptor is outside the shared cache.

rdar://93931813
2022-06-17 16:45:22 -04:00
zoecarver
f972f664d3 [cxx-interop] Runtime support for foreign reference types. 2022-06-14 12:18:05 -07:00
Mike Ash
de93c3e182 [Runtime] Skip shared cache protocol conformance queries we know won't succeed.
The shared cache tables can only point to things within the shared cache, so if the protocol, ObjC class, or type descriptor are outside the shared cache, we know that the lookup will fail and we can skip it.

rdar://90427793
2022-05-10 15:25:23 -04:00
Saleem Abdulrasool
a8b0ee24dc runtime: blanket application of namespacing and inclusion of new
Apply a blanket pass of including `new` for the placement new allocation
and namespacing the call to the global placement new allocator.  This
should repair the Android ARMv7 builds.
2022-04-14 14:21:12 -07:00
Mike Ash
d61fee3884 [Runtime] Check the weak-linked _dyld_has_preoptimized_swift_protocol_conformances for NULL before calling it.
rdar://89522018
2022-03-02 14:24:12 -05:00
Mike Ash
99752c5d08 [Runtime] Fix dyld protocol conformances.
Leftover code was overwriting the result from the `on_disk` calls. Don't do that.

While we're in there, change the name of the `DYLD_CONFORMANCES_LOG` macro to `DYLD_CONFORMANCES_LOG` and fix up the wording to be more general.

rdar://89154273
2022-02-21 15:47:21 -05:00
Mike Ash
d262acfa04 [Runtime] Support precomputed protocol conformances outside the shared cache.
Extend the support for precomputed protocol conformances in the shared cache. When available, we'll query dyld for conformances in optimized images loaded outside the shared cache. This is a relatively small addition; where we previously checked the shared cache, we now check both. The order is conditionalized on `scanSectionsBackwards` to preserve that behavior. We also rename some identifiers to fit this more expansive use of preoptimized conformances.

rdar://87425446
2022-02-03 13:30:39 -05:00
Alastair Houghton
4a3612b873 Merge pull request #40955 from al45tair/problem/86368350
[Runtime] Fix a potential NULL pointer dereference.
2022-01-21 21:32:05 +00:00
Alastair Houghton
a0313e9538 [Runtime] Fix a potential NULL pointer dereference.
If we find multiple conformances for the same protocol, we generate a
warning.  This works fine for Swift types, but for Objective-C types
it's possible that while generating the warning we might find that the
type description is NULL.

Fix by using swift_getTypeName().

rdar://86368350
2022-01-21 17:42:02 +00:00
Adrian Prantl
fede775269 Make Objective-C interoperability configurable in the runtime
In order to be able to debug, for example, a Linux process from a macOS host, we
need to be able to initialize a ReflectionContext without Objective-C
interoperability. This patch turns ObjCInterOp into another template trait, so
it's possible to instantiate a non-ObjC MetadataReader on a system built with
ObjC-interop (but not vice versa).

This patch changes the class hierarchy to

                          TargetMetadata<Runtime>
                                    |
                          TargetHeapMetadata<Runtime>
                                    |
                          TargetAnyClassMetadata<Runtime>
                                   /                \
                                  /               TargetAnyClassMetadataObjCInterop<Runtime>
                                 /                              \
TargetClassMetadata<Runtime, TargetAnyClassMetadata<Runtime>>    \
                                                                  \
                    TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>

TargetAnyClassMetadataObjCInterop inherits from TargetAnyClassMetadata because
most of the implementation is the same. This choice makes TargetClassMetadata a
bit tricky. In this patch I went with templating the parent class.

rdar://87179578
2022-01-20 18:28:18 -08:00
tbkka
184488d3f2 Conditionalize the fix for SR-14635 (#40822)
* Refactor Bincompat

Organize everything around internal functions that test for
a particular OS version.

Correctly handle cases where we don't know the version of the app.

Make all bincompat functions consistently return `true` for the
legacy semantics, `false` for new semantics.  Consistently name
them all to reflect this.

* Conditionalize the support for SR-14635

SR-14635 pointed out a hole in the updated dynamic casting logic
that allowed certain casts that should have been illegal.

In particular, when casting certain types to Obj-C protocols,
the Swift value gets boxed; we would permit the cast to succeed
whenever the resulting box satisfied the protocol.  For example,
this allowed any Swift value to be cast to `NSCopying` regardless of
whether or not it implemented the required `copy(with:)` method.

This was fixed in #37683 to reject such casts but of course some folks were
depending on this behavior to pass Swift data into Obj-C functions.
(The properly supported approach for passing arbitrary Swift data into
Obj-C functions is to cast the Swift value to `AnyObject`.)

This change makes that new behavior conditional.  For now,
the legacy semantics are enabled on Apple platforms and the
new semantics are in use everywhere else.  This will allow
us to gradually enable enforcement of the new behavior over
time.

* Just skip this test on Apple platforms, since it is inconsistently implemented there (and is therefore not really testable)
2022-01-14 11:56:25 -08:00
Jonathan Grynspan
099fdc2e41 Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.) 2022-01-01 11:39:25 -05:00
Arnold Schwaighofer
cf3951394a Revert "Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.)" 2021-12-21 07:15:08 -08:00
Jonathan Grynspan
7fe5ea7398 Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.) 2021-12-20 15:15:02 -05:00
Mike Ash
aec4ec4c4a [Runtime] Weakly import dyld protocol conformance functions.
This allows us to build against a macOS 12 SDK and test on macOS 11.

rdar://81133606
2021-07-29 14:42:30 -04:00
Mike Ash
b37252d418 [Runtime] Fix infinite recursion in protocol conformance checking on class Sub: Super<Sub>.
Conformance checks now walk the superclass chain in two stages: stage 1 only walks superclasses that have already been instantiated. When there's a negative result and there's an uninstantiated superclass, then stage 2 will walk the uninstantiated superclasses.

The infinite recursion would occur in this scenario:

    class Super<T: P> {}
    class Sub: Super<Sub>, P {}

Instantiating the metadata for Super requires looking up the conformance for Sub: P. Conformance checking for Sub would instantiate the metadata for Super to check for a Super: P conformance.

The compiler does not allow the conformance to come from a superclass in this situation. This does not compile:

    class Super<T: P>: P {}
    class Sub: Super<Sub> {}

Therefore it's not necessary to look at Super when finding the conformance for Sub: P in this particular case. The trick is knowing when to skip Super.

We do need to instantiate Super in the general case, otherwise we can get false negatives. This was addressed in a80fe8536b, which walks the full superclass chain during conformance checks, even if the superclass has not yet been instantiated. Unfortunately, that causes this infinite recursion.

This fix modifies that fix to make superclass instantiation conditional. The result is the ability to choose between the old algorithm (which skipped uninstantiated superclasses, albeit somewhat by accident) and the new one. A small wrapper then runs the check with the old algorithm, and then only if the old algorithm fails and there is an uninstantiated superclass, it runs with the new one.

Uninstantiated superclasses are uncommon and transient (you only run into this while metadata is in the process of being constructed) so 99.9999% of the time we'll just run the first stage and be done, and performance should remain the same as before.

rdar://80532245
2021-07-22 13:46:01 -04:00
Mike Ash
06ff648825 [Runtime] Fix protocol conformance checks on pure ObjC classes.
The getSuperclassForMaybeIncompleteMetadata function assumes Swift metadata, and can malfunction strangely when given a pure ObjC class. This is rare, as we usually get the Swift wrapper metadata instead, but possible when using calls like objc_copyClassList.

Fix this by checking for isTypeMetadata before doing anything that assumes Swift-metadata-ness.

rdar://80336030
2021-07-08 17:45:43 -04:00
Mike Ash
53fe241c0e Merge pull request #37973 from mikeash/fix-protocol-conformance-KVO
[Runtime] Fix crash in protocol conformance checks on KVO artificial subclasses.
2021-06-23 09:12:32 -04:00
Mike Ash
c3aa44368a [Runtime] Fix crash in protocol conformance checks on KVO artificial subclasses.
tryGetCompleteMetadataNonblocking crashes on artificial subclasses due to the NULL type descriptor. Explicitly check for artificial subclasses in getSuperclassForMaybeIncompleteMetadata and immediately return their Superclass field. Artificial subclasses are always fully initialized so we don't need to do anything special for them.

rdar://72583931
2021-06-17 14:45:58 -04:00
Alastair Houghton
4794b4b28c [Runtime] Detect and log redundant subclass/superclass conformances.
When we rely on a protocol conformance, and the type in question has multiple
conformances to that protocol in its inheritance chain, emit a runtime warning.

It's quite tricky to cause this problem - you need a type in one dylib that is
extended to conform to a protocol in another dylib, subclassed in another module
and then some subclass has protocol conformance added as well.  If they're in
the same module, the compiler will give an error and prevent the problem
completely.

rdar://73364629
2021-06-17 19:28:27 +01:00