-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CFI: Support self_cell-like recursion
Current `transform_ty` attempts to avoid cycles when normalizing `#[repr(transparent)]` types to their interior, but runs afoul of this pattern used in `self_cell`: ``` struct X<T> { x: u8, p: PhantomData<T>, } #[repr(transparent)] struct Y(X<Y>); ``` When attempting to normalize Y, it will still cycle indefinitely. By using a types-visited list, this will instead get expanded exactly one layer deep to X<Y>, and then stop, not attempting to normalize `Y` any further.
- Loading branch information
Showing
2 changed files
with
77 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Check that encoding self-referential types works with #[repr(transparent)] | ||
|
||
//@ needs-sanitizer-cfi | ||
// FIXME(#122848) Remove only-linux once OSX CFI binaries work | ||
//@ only-linux | ||
//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi | ||
//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 | ||
//@ run-pass | ||
|
||
use std::marker::PhantomData; | ||
|
||
struct X<T> { | ||
_x: u8, | ||
p: PhantomData<T>, | ||
} | ||
|
||
#[repr(transparent)] | ||
struct Y(X<Y>); | ||
|
||
trait Fooable { | ||
fn foo(&self, y: Y); | ||
} | ||
|
||
struct Bar; | ||
|
||
impl Fooable for Bar { | ||
fn foo(&self, _: Y) {} | ||
} | ||
|
||
fn main() { | ||
let x = &Bar as &dyn Fooable; | ||
x.foo(Y(X {_x: 0, p: PhantomData})); | ||
} |