Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscompilation caused by incorrectly-deduced readonly on virtual call #137646

Open
johnbwang opened this issue Feb 26, 2025 · 21 comments
Open

Miscompilation caused by incorrectly-deduced readonly on virtual call #137646

johnbwang opened this issue Feb 26, 2025 · 21 comments
Assignees
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-miscompile Issue: Correct Rust code lowers to incorrect machine code I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-critical Critical priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@johnbwang
Copy link

johnbwang commented Feb 26, 2025

I tried the following code. It requires a binary crate and a library crate.

main.rs

fn main() {
    let mut struct_c = lib::StructC::new();
    let struct_a = lib::StructA { a: 1, b: 2, c: 3 };
    lib::run(&mut struct_c, struct_a);
}

main's Cargo.toml

[package]
name = "compilerbug"
version = "0.1.0"
edition = "2024"

[dependencies]
lib = { path = "./lib" }

[profile.dev]
opt-level = 1
incremental = false

lib.rs

#[derive(Clone, Copy)]
pub struct StructA {
    pub a: i32,
    pub b: i32,
    pub c: i32,
}

pub trait TraitA {}

pub struct StructB {}

impl StructB {
    pub fn new() -> Self {
        Self {}
    }
}

impl TraitA for StructB {}

pub trait TraitB {
    fn get_trait_a(&self, struct_a: StructA) -> Option<Box<dyn TraitA>> {
        Some(Box::new(StructB::new()))
    }
}

pub struct StructC {}

impl StructC {
    pub fn new() -> Self {
        Self {}
    }
}

impl TraitB for StructC {
    fn get_trait_a(&self, mut struct_a: StructA) -> Option<Box<dyn TraitA>> {
        struct_a.a = i32::MAX;
        Some(Box::new(StructB::new()))
    }
}

#[inline(never)]
fn print_struct_a(struct_a: StructA) {
    println!("{}", struct_a.a);
}

#[inline(never)]
pub fn run(trait_b: &mut dyn TraitB, struct_a: StructA) {
    print_struct_a(struct_a);
    trait_b.get_trait_a(struct_a);
    print_struct_a(struct_a);

    // Uncommenting the following will fix the code.
    // println!("{}", struct_a.a);
}

lib's Cargo.toml

[package]
name = "lib"
version = "0.1.0"
edition = "2024"

Since struct_a conforms to Copy, passing struct_a to get_trait_a() should make a copy. Instead, when modifying struct_a inside of get_trait_a(), it modifies the original. When printing the struct a second time, the struct has been modified. To repro the bug, it requires opt-level >= 1 and incremental = false.

I expected the output in my command line to be:

1
1

Instead, this happened:

1
2147483647

Meta

rustc --version --verbose:

rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: aarch64-apple-darwin
release: 1.85.0
LLVM version: 19.1.7
@johnbwang johnbwang added the C-bug Category: This is a bug. label Feb 26, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 26, 2025
@johnbwang johnbwang changed the title Large Copy types breaks expected Copy semantics Large Copy types breaks expected Copy semantics Feb 26, 2025
@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

searched toolchains nightly-2023-10-01 through nightly-2023-11-11


********************************************************************************
Regression in nightly-2023-10-09
********************************************************************************

fetching https://static.rust-lang.org/dist/2023-10-08/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-10-08: 40 B / 40 B [==================================] 100.00 % 501.91 KB/s converted 2023-10-08 to 97c81e1b537088f1881c8894ee8579812ed9b6d1
fetching https://static.rust-lang.org/dist/2023-10-09/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-10-09: 40 B / 40 B [==================================] 100.00 % 348.89 KB/s converted 2023-10-09 to bf9a1c8a193fc373897196321215794c8bebbeec
looking for regression commit between 2023-10-08 and 2023-10-09
fetching (via remote github) commits from max(97c81e1b537088f1881c8894ee8579812ed9b6d1, 2023-10-06) to bf9a1c8a193fc373897196321215794c8bebbeec
ending github query because we found starting sha: 97c81e1b537088f1881c8894ee8579812ed9b6d1
get_commits_between returning commits, len: 10
  commit[0] 2023-10-07: Auto merge of #116416 - Kobzol:ci-host-llvm-17-0-2, r=Mark-Simulacrum
  commit[1] 2023-10-08: Auto merge of #114623 - Kobzol:opt-dist-gha-summaries, r=Mark-Simulacrum
  commit[2] 2023-10-08: Auto merge of #116450 - Kobzol:automation-try-bors-ci, r=Mark-Simulacrum
  commit[3] 2023-10-08: Auto merge of #116486 - van-ema:master, r=nikic
  commit[4] 2023-10-08: Auto merge of #116487 - tamird:avoid-unwrap-absolute, r=bjorn3
  commit[5] 2023-10-08: Auto merge of #116509 - Enselic:rustc-test-op, r=Mark-Simulacrum
  commit[6] 2023-10-08: Auto merge of #116514 - petrochenkov:nogccld, r=lqd
  commit[7] 2023-10-08: Auto merge of #116183 - cjgillot:debug-dse-always, r=oli-obk
  commit[8] 2023-10-08: Auto merge of #116454 - tmiasko:small-dominators, r=cjgillot
  commit[9] 2023-10-08: Auto merge of #116515 - petrochenkov:nolegflavor, r=lqd
ERROR: no CI builds available between 97c81e1b537088f1881c8894ee8579812ed9b6d1 and bf9a1c8a193fc373897196321215794c8bebbeec within last 167 days

well… among those that’s probably the LLVM bump then, right?

@theemathas
Copy link
Contributor

Might also be #116454

@saethlin saethlin added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. I-miscompile Issue: Correct Rust code lowers to incorrect machine code labels Feb 26, 2025
@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

Interestingly, with the

// Uncommenting the following will fix the code.

marked section uncommented (and fixed to refer to struct_a by the correct name), it’s also still broken for old Rust versions; regressing at the same point as before (2023-10-09), and actually being “fixed” again only at the following point:

searched toolchains nightly-2024-06-07 through nightly-2024-07-20


********************************************************************************
Regression in nightly-2024-06-29
********************************************************************************

fetching https://static.rust-lang.org/dist/2024-06-28/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2024-06-28: 40 B / 40 B [====================================] 100.00 % 1.15 MB/s converted 2024-06-28 to 9c3bc805dd9cb84019c124b9a50fdff1e62a7ec9
fetching https://static.rust-lang.org/dist/2024-06-29/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2024-06-29: 40 B / 40 B [====================================] 100.00 % 1.06 MB/s converted 2024-06-29 to e9e6e2e444c30c23a9c878a88fbc3978c2acad95
looking for regression commit between 2024-06-28 and 2024-06-29
fetching (via remote github) commits from max(9c3bc805dd9cb84019c124b9a50fdff1e62a7ec9, 2024-06-26) to e9e6e2e444c30c23a9c878a88fbc3978c2acad95
ending github query because we found starting sha: 9c3bc805dd9cb84019c124b9a50fdff1e62a7ec9
get_commits_between returning commits, len: 5
  commit[0] 2024-06-27: Auto merge of #127049 - flip1995:clippy-subtree-update, r=Manishearth
  commit[1] 2024-06-28: Auto merge of #127010 - GuillaumeGomez:update-puppeteer, r=notriddle
  commit[2] 2024-06-28: Auto merge of #127076 - matthiaskrgr:rollup-l01gm36, r=matthiaskrgr
  commit[3] 2024-06-28: Auto merge of #127000 - Oneirical:no-test-for-the-wicked, r=Kobzol
  commit[4] 2024-06-28: Auto merge of #126701 - onur-ozkan:build-lld-if-enabled, r=Kobzol
ERROR: no CI builds available between 9c3bc805dd9cb84019c124b9a50fdff1e62a7ec9 and e9e6e2e444c30c23a9c878a88fbc3978c2acad95 within last 167 days

I don’t know, is that this one perhaps?

@moxian

This comment has been minimized.

@steffahn
Copy link
Member

It also isn’t “fixed” by uncommenting the indicated line, if opt-level = 1 is used.

@saethlin saethlin added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Feb 26, 2025
@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

It’s really interesting how it seems to be relevant whether or not the default method body does mutate its argument. E.g.:

pub trait Trait {
    fn method(&self, mut arr: [i32; 3]) {
        println!("{:p}", &arr[0]);

        // uncomment to "fix":
        // println!("{:p}", &mut arr[0]);
    }
}

impl Trait for () {
    fn method(&self, mut arr: [i32; 3]) {
        arr[0] = 42;
    }
}

fn inspect_arr(arr: [i32; 3]) {
    assert_eq!(format!("{}", arr[0]), "0");
}

pub fn run(trait_b: & dyn Trait, arr: [i32; 3]) {
    inspect_arr(arr);
    trait_b.method(arr);
    inspect_arr(arr);
}
use name_of_crate::*;

fn main() {
    run(&(), [0, 0, 0]);
}

here the println!("{:p}", &mut arr[0]); (or various other things that mutably access or actually mutate arr) do make a difference.

@moxian
Copy link
Contributor

moxian commented Feb 26, 2025

With -Zmir-opt-level=0 (thanks @saethlin for the pointer) it reproduces way further back to nightly-2023-07-16:

********************************************************************************
Regression in nightly-2023-07-16
********************************************************************************

fetching https://static.rust-lang.org/dist/2023-07-15/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-07-15: 40 B / 40 B [=======================================================] 100.00 % 62.59 KB/s converted 2023-07-15 to ad963232d9b987d66a6f8e6ec4141f672b8b9900
fetching https://static.rust-lang.org/dist/2023-07-16/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-07-16: 40 B / 40 B [======================================================] 100.00 % 174.93 KB/s converted 2023-07-16 to 4c8bb79d9f565115637cc6da739f8389e79f3a29
looking for regression commit between 2023-07-15 and 2023-07-16
fetching (via remote github) commits from max(ad963232d9b987d66a6f8e6ec4141f672b8b9900, 2023-07-13) to 4c8bb79d9f565115637cc6da739f8389e79f3a29
ending github query because we found starting sha: ad963232d9b987d66a6f8e6ec4141f672b8b9900
get_commits_between returning commits, len: 5
  commit[0] 2023-07-14: Auto merge of #113471 - compiler-errors:new-solver-norm-escaping, r=lcnr
  commit[1] 2023-07-15: Auto merge of #113514 - jyn514:more-gha-groups, r=oli-obk
  commit[2] 2023-07-15: Auto merge of #112157 - erikdesjardins:align, r=nikic
  commit[3] 2023-07-15: Auto merge of #113732 - matthiaskrgr:rollup-nm5qy4i, r=matthiaskrgr
  commit[4] 2023-07-15: Auto merge of #113697 - GuillaumeGomez:rm-unneeded-externallocation-handling, r=lqd
ERROR: no CI builds available between ad963232d9b987d66a6f8e6ec4141f672b8b9900 and 4c8bb79d9f565115637cc6da739f8389e79f3a29 within last 167 days

- #112157 sounds related maybe?

@steffahn
Copy link
Member

That’s funny, my bisection (of my reduced example) with -Zmir-opt-level=0 also reproduces further back but not quite as far: only up to

searched toolchains nightly-2023-08-20 through nightly-2023-10-01


********************************************************************************
Regression in nightly-2023-08-27
********************************************************************************

fetching https://static.rust-lang.org/dist/2023-08-26/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-08-26: 40 B / 40 B [=======================================================] 100.00 % 566.52 KB/s converted 2023-08-26 to 734a0d0aa0d5cab60f94f6d0c6a014dae12915f1
fetching https://static.rust-lang.org/dist/2023-08-27/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-08-27: 40 B / 40 B [=======================================================] 100.00 % 351.72 KB/s converted 2023-08-27 to 69e97df5ce571a777acd654ec3697ae8d25962ea
looking for regression commit between 2023-08-26 and 2023-08-27
fetching (via remote github) commits from max(734a0d0aa0d5cab60f94f6d0c6a014dae12915f1, 2023-08-24) to 69e97df5ce571a777acd654ec3697ae8d25962ea
ending github query because we found starting sha: 734a0d0aa0d5cab60f94f6d0c6a014dae12915f1
get_commits_between returning commits, len: 10
  commit[0] 2023-08-25: Auto merge of #115202 - ouz-a:more_smir, r=spastorino
  commit[1] 2023-08-25: Auto merge of #115221 - compiler-errors:walk-path, r=estebank
  commit[2] 2023-08-26: Auto merge of #115211 - spastorino:add-missing-smir-generics-of, r=compiler-errors
  commit[3] 2023-08-26: Auto merge of #115228 - saethlin:is-interrupted, r=thomcc
  commit[4] 2023-08-26: Auto merge of #115236 - scottmcm:less-vector, r=compiler-errors
  commit[5] 2023-08-26: Auto merge of #115232 - wesleywiser:revert_114643, r=tmiasko
  commit[6] 2023-08-26: Auto merge of #115243 - weihanglo:update-cargo, r=weihanglo
  commit[7] 2023-08-26: Auto merge of #115246 - matthiaskrgr:rollup-zdiw9gt, r=matthiaskrgr
  commit[8] 2023-08-26: Auto merge of #115198 - Zoxc:query-panic-wait, r=cjgillot
  commit[9] 2023-08-26: Auto merge of #115224 - spastorino:remove-lub_empty, r=lcnr
ERROR: no CI builds available between 734a0d0aa0d5cab60f94f6d0c6a014dae12915f1 and 69e97df5ce571a777acd654ec3697ae8d25962ea within last 167 days

oh well… this might be because I use an array…

most likely that regression point was related to

because the regression was also mismatching between nightly and stable, suggesting a back-port…

Ah yes, with a tuple instead of an array I do get nightly-2023-07-16 as well :-)

@moxian
Copy link
Contributor

moxian commented Feb 26, 2025

I looked at LLVM IR, and realized I can't really read it myself, but I can at least share it here to save other folks some trouble:
https://godbolt.org/z/6znK7E3Md (original example, 1.72.0 - 1.73.0 )
https://godbolt.org/z/bjcEGn8s1 (slightly modified steffahn's [i8;12] reduction, 1.69.0 - 1.70.0)

@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

oh well… we can go back even further… with an unaligned type! [i8; 12] works – or a tuple of the same size – (bisecting…)

edit: done:

searched toolchains nightly-2023-03-04 through nightly-2023-04-15


********************************************************************************
Regression in nightly-2023-03-26
********************************************************************************

fetching https://static.rust-lang.org/dist/2023-03-25/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-03-25: 40 B / 40 B [=======================================================] 100.00 % 366.18 KB/s converted 2023-03-25 to 8be3c2bda6b683f87b24714ba595e8b04faef54c
fetching https://static.rust-lang.org/dist/2023-03-26/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2023-03-26: 40 B / 40 B [=======================================================] 100.00 % 563.99 KB/s converted 2023-03-26 to 0c61c7a978fe9f7b77a1d667c77d2202dadd1c10
looking for regression commit between 2023-03-25 and 2023-03-26
fetching (via remote github) commits from max(8be3c2bda6b683f87b24714ba595e8b04faef54c, 2023-03-23) to 0c61c7a978fe9f7b77a1d667c77d2202dadd1c10
ending github query because we found starting sha: 8be3c2bda6b683f87b24714ba595e8b04faef54c
get_commits_between returning commits, len: 9
  commit[0] 2023-03-24: Auto merge of #107932 - petrochenkov:onlyexport, r=jyn514
  commit[1] 2023-03-24: Auto merge of #109399 - petrochenkov:rendersort, r=GuillaumeGomez
  commit[2] 2023-03-25: Auto merge of #109546 - saethlin:inline-into, r=scottmcm
  commit[3] 2023-03-25: Auto merge of #99929 - the8472:default-iters, r=scottmcm
  commit[4] 2023-03-25: Auto merge of #109371 - Zoxc:verify-hash-opt, r=cjgillot
  commit[5] 2023-03-25: Auto merge of #109100 - Zoxc:merge-query-try, r=cjgillot
  commit[6] 2023-03-25: Auto merge of #109581 - matthiaskrgr:rollup-e8fi2vi, r=matthiaskrgr
  commit[7] 2023-03-25: Auto merge of #109458 - Nilstrieb:smol-cute-little-bits, r=wesleywiser
  commit[8] 2023-03-25: Auto merge of #109474 - nikic:llvm-16-again, r=cuviper
ERROR: no CI builds available between 8be3c2bda6b683f87b24714ba595e8b04faef54c and 0c61c7a978fe9f7b77a1d667c77d2202dadd1c10 within last 167 days

@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

Now, this last bisection might be an LLVM upgrade, after all?

@moxian
Copy link
Contributor

moxian commented Feb 26, 2025

So, if i'm reading this right (not sure about this one), we are working with this unoptimized llvm ir:

define void @_ZN7example3run17h6794af29876d6ee8E(ptr align 1 %trait_b.0, ptr align 8 %trait_b.1, ptr %arr) unnamed_addr #0 {
  %_5 = alloca [12 x i8], align 1
  call void @llvm.memcpy.p0.p0.i64(ptr align 1 %_5, ptr align 1 %arr, i64 12, i1 false)
  %0 = getelementptr inbounds ptr, ptr %trait_b.1, i64 3
  %1 = load ptr, ptr %0, align 8, !invariant.load !2, !nonnull !2
  call void %1(ptr align 1 %trait_b.0, ptr %_5)
  ret void
}

and llvm15 leaves it mostly as is

define void @_ZN7example3run17h6794af29876d6ee8E(ptr noundef nonnull align 1 %trait_b.0, ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %trait_b.1, ptr noalias nocapture noundef readonly dereferenceable(12) %arr) unnamed_addr #1 {
  %_5 = alloca [12 x i8], align 1
  call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %_5)
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(12) %_5, ptr noundef nonnull align 1 dereferenceable(12) %arr, i64 12, i1 false)
  %0 = getelementptr inbounds ptr, ptr %trait_b.1, i64 3
  %1 = load ptr, ptr %0, align 8, !invariant.load !2, !nonnull !2
  call void %1(ptr noundef nonnull align 1 %trait_b.0, ptr noalias nocapture noundef nonnull readonly dereferenceable(12) %_5)
  call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %_5)
  ret void
}

while llvm 16 elides the alloca+memcpy copy and transforms it into a tail call? Which means we are operating on the "original" data, and not on the copy anymore(?).

define void @_ZN7example3run17h7445f22c4a90eb2aE(ptr noundef nonnull align 1 %trait_b.0, ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %trait_b.1, ptr noalias nocapture noundef readonly dereferenceable(12) %arr) unnamed_addr #1 {
  %0 = getelementptr inbounds ptr, ptr %trait_b.1, i64 3
  %1 = load ptr, ptr %0, align 8, !invariant.load !2, !nonnull !2
  tail call void %1(ptr noundef nonnull align 1 %trait_b.0, ptr noalias nocapture noundef nonnull readonly dereferenceable(12) %arr)
  ret void
}

At least that's what I get from staring at the godbolt, but i'm really out of my depths here...

@DianQK
Copy link
Member

DianQK commented Feb 26, 2025

It seems we might not need to keep bisecting. It looks like parameters are being passed by reference, not by value.
https://rust.godbolt.org/z/6jo19ErYM

@steffahn
Copy link
Member

tail call void %1(ptr noundef nonnull align 1 %trait_b.0, ptr noalias nocapture noundef nonnull readonly dereferenceable(12) %arr)

contains

ptr noalias nocapture noundef nonnull readonly dereferenceable(12) %arr

the question is – where does this “readonly” come from? Is it correct?

As far as I can tell, the actual method – which also makes it into the vtable – is instead

ptr noalias nocapture noundef writeonly align 1 dereferenceable(12) %arr

That being said, these properties – readonly or not – of course cannot actually be known by the caller in the run method. They can only work with the trait declaration, because they must support all possible implementor.

It thus also doesn’t surprise me if the trait method’s default implementation somehow influences this miscompilation.

@saethlin
Copy link
Member

The readonly probably comes from

pub(super) fn deduced_param_attrs<'tcx>(

@steffahn
Copy link
Member

Copy for the passed types is fairly irrelevant: Example without Copy:

pub struct Foo(i32, i32, i32);

pub trait Trait {
    fn methodd(&self, mut foo: Foo) {
        println!("{:p}", &foo.0);

        // uncomment to "fix":
        //println!("{:p}", &mut foo.0);
    }
}

impl Trait for () {
    fn methodd(&self, mut foo: Foo) {
        foo.0 = 42;
    }
}

fn inspect_foo(foo: Foo) {
    assert_eq!(format!("{}", foo.0), "1");
}

pub fn run(trait_b: &dyn Trait) {
    inspect_foo(Foo(1, 2, 3));
    trait_b.methodd(Foo(1, 2, 3));
    inspect_foo(Foo(1, 2, 3));
}

pub fn call() {
    run(&());
}
use name_of_crate::*;

fn main() {
    call();
}
assertion `left == right` failed
  left: "42"
 right: "1"

@DianQK
Copy link
Member

DianQK commented Feb 26, 2025

I want to dig into it.
@rustbot claim

@steffahn
Copy link
Member

steffahn commented Feb 26, 2025

black_box helps make it single-crate. E.g.:

use std::hint::black_box;

type T = (i32, i32, i32);

pub trait Trait {
    fn m(&self, _: T, _: T) {}
}

impl Trait for () {
    fn m(&self, mut _foo: T, foo2: T) {
        _foo = (0, 0, 0);
        println!("{foo2:?}");
    }
}

pub fn run(trait_b: &dyn Trait) {
    trait_b.m((1, 1, 1), (1, 1, 1));
}

pub fn call() {
    run(&());
}

fn main() {
    black_box(run as fn(&dyn Trait));
    call();
}

(playground)

@theemathas
Copy link
Contributor

Of note: steffahn's reproducer above changed the behavior from "value that shouldn't be modified is modified" to "a garbage (uninitialized?) value is printed".

Also,
@rustbot labels +regression-from-stable-to-stable

@rustbot rustbot added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Feb 26, 2025
@Noratrieb Noratrieb added I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 26, 2025
@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-critical

@rustbot rustbot added P-critical Critical priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Feb 26, 2025
DianQK added a commit to DianQK/rust that referenced this issue Feb 26, 2025
@DianQK
Copy link
Member

DianQK commented Feb 26, 2025

#137669 should fix this.

@saethlin Free to review if you would like.

@saethlin saethlin changed the title Large Copy types breaks expected Copy semantics Miscompilation caused by incorrectly-deduced readonly on virtual call Feb 26, 2025
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 27, 2025
Don't infer attributes of virtual calls based on the function body

Fixes (after backport) rust-lang#137646.
Since we don't know the exact implementation of the virtual call, it might write to parameters, we can't infer the readonly attribute.
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 28, 2025
Don't infer attributes of virtual calls based on the function body

Fixes (after backport) rust-lang#137646.
Since we don't know the exact implementation of the virtual call, it might write to parameters, we can't infer the readonly attribute.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-miscompile Issue: Correct Rust code lowers to incorrect machine code I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-critical Critical priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants