about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/ty/instance.rs
diff options
context:
space:
mode:
authorMatthew Maurer <mmaurer@google.com>2024-03-25 17:23:55 +0000
committerMatthew Maurer <mmaurer@google.com>2024-04-02 19:11:16 +0000
commit473a70de8457645df7a49558d6ba27405f966ee0 (patch)
treed100972ea77c26933a4e7ea224a97f319f9df2cd /compiler/rustc_middle/src/ty/instance.rs
parent6aa89f684e4427a9d08e35b572f9071705105140 (diff)
downloadrust-473a70de8457645df7a49558d6ba27405f966ee0.tar.gz
rust-473a70de8457645df7a49558d6ba27405f966ee0.zip
CFI: Support function pointers for trait methods
Adds support for both CFI and KCFI for attaching concrete and abstract
types to functions. KCFI does this through generation of `ReifyShim` on
any function pointer that could go in a vtable, and checking the
`ReifyReason` when emitting the instance. CFI does this by attaching
both the concrete and abstract type to every instance.

TypeID codegen tests are switched to be anchored on the left rather than
the right in order to allow emission of additional type attachments.

Fixes #115953
Diffstat (limited to 'compiler/rustc_middle/src/ty/instance.rs')
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index e5625c8a5c6..4a7720b38f8 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -517,6 +517,24 @@ impl<'tcx> Instance<'tcx> {
                     debug!(" => fn pointer created for virtual call");
                     resolved.def = InstanceDef::ReifyShim(def_id, reason);
                 }
+                // Reify `Trait::method` implementations if KCFI is enabled
+                // FIXME(maurer) only reify it if it is a vtable-safe function
+                _ if tcx.sess.is_sanitizer_kcfi_enabled()
+                    && tcx.associated_item(def_id).trait_item_def_id.is_some() =>
+                {
+                    // If this function could also go in a vtable, we need to `ReifyShim` it with
+                    // KCFI because it can only attach one type per function.
+                    resolved.def = InstanceDef::ReifyShim(resolved.def_id(), reason)
+                }
+                // Reify `::call`-like method implementations if KCFI is enabled
+                _ if tcx.sess.is_sanitizer_kcfi_enabled()
+                    && tcx.is_closure_like(resolved.def_id()) =>
+                {
+                    // Reroute through a reify via the *unresolved* instance. The resolved one can't
+                    // be directly reified because it's closure-like. The reify can handle the
+                    // unresolved instance.
+                    resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args }
+                }
                 _ => {}
             }