Rust: Laporkan kondisi out-of-bound indeks const sebelumnya

Dibuat pada 10 Agu 2012  ·  24Komentar  ·  Sumber: rust-lang/rust

Saat ini jika Anda mencoba mengindeks ke vektor const, dalam const expr, kami melaporkan batas-terlampaui akhir dalam kompilasi -- selama penerjemahan. Kita harus memperhatikannya lebih awal, di pass evaluasi const.

A-diagnostics C-cleanup P-low T-compiler

Komentar yang paling membantu

Ya saya pikir kita sudah selesai dengan masalah ini setelah 6 tahun :tertawa:

Semua 24 komentar

Rupanya "kesalahan" yang dihasilkan ini tidak menyebabkan kompilasi gagal — kode akan dibuat dan rustc akan mengembalikan 0. LLVM akan mengeluh jika indeks secara fisik di luar batas, dan ini saat ini selalu setara dengan di luar batas index (saya pikir), tapi itu tidak berlaku untuk irisan const.

Ini sangat tidak terduga selama pengujian, yang (kecuali untuk check-fast, rupanya?) Tidak menunjukkan output/kesalahan saat berhasil.

Tidak kritis untuk 0,6; menghilangkan tonggak sejarah

Nominasi untuk pencapaian 5, siap produksi

diterima untuk pencapaian siap produksi

Sebagai contoh dari apa yang saya percaya bahwa ini bicarakan:

static a: &'static [int] = &[];
static b: int = a[1];

fn main() {}

hasil

$ rustc foo.rs
foo.rs:2:16: 2:19 error: const index-expr is out of bounds
foo.rs:2 static b: int = a[1];
                         ^~~
Assertion failed: (ReqTy && "extractvalue indices invalid!"), function getExtractValue, file ../../../../src/llvm/lib/IR/Constants.cpp, line 1982.
zsh: abort      rustc foo.rs

Tampaknya buruk bahwa kami memukul pernyataan LLVM sama sekali.

Diterima untuk P-rendah.

Triase: Contoh @alexcrichton (9 bulan) masih valid secara sintaksis (yay!) dan masih gagal dengan pernyataan itu (boo!).

Saya percaya ini sudah diperbaiki .

Jika Anda memperbarui contoh @alexcrichton :

#![allow(dead_code)]
const A: &'static [usize] = &[];
const B: usize = A[1];

fn main() {}

Sekarang berhasil mengkompilasi

Hanya sekali Anda mencoba menggunakan nilai yang tidak valid B rustc mengalami masalah.

#![allow(dead_code)]
const A: &'static [usize] = &[];
const B: usize = A[1];

fn main() {
    println!("B={}", B);
}
<anon>:3:18: 3:22 error: const index-expr is out of bounds
<anon>:3 const B: usize = A[1];
                          ^~~~
rustc: /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/lib/IR/Constants.cpp:2174: static llvm::Constant* llvm::ConstantExpr::getExtractValue(llvm::Constant*, llvm::ArrayRef<unsigned int>, llvm::Type*): Assertion `ReqTy && "extractvalue indices invalid!"' failed.
Aborted (core dumped)
playpen: application terminated with error code 134

kesalahan: tidak dapat merujuk ke statika lain berdasarkan nilai, gunakan alamat-operator atau konstanta

Ya, sepertinya bagus.

tunggu, contoh @JustAPerson sepertinya tidak cocok untuk saya. Pembukaan kembali.

Saya pikir ini sekarang diperbaiki secara nyata:

$ cat foo.rs
#![allow(dead_code)]
const A: &'static [usize] = &[];
const B: usize = A[1];

fn main() {
    println!("B={}", B);
}
$ rustc foo.rs
foo.rs:3:18: 3:22 error: const index-expr is out of bounds
foo.rs:3 const B: usize = A[1];
                          ^~~~
error: aborting due to previous error
$ rustc --version
rustc 1.0.0-dev (a691f1eef 2015-04-15) (built 2015-04-15)

Jadi, dalam 11 hari terakhir:

hello.rs:3:18: 3:22 error: const index-expr is out of bounds
hello.rs:3 const B: usize = A[1];
                            ^~~~
rustc: /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::SequentialType; Y = llvm::Type; typename llvm::cast_retty<X, Y*>::ret_type = llvm::SequentialType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

soooo sepertinya sudah mundur?

Guh, ini adalah kesalahan saya. Saya membuat laporan di atas menggunakan toolchain yang dikompilasi dengan pernyataan LLVM dinonaktifkan (yang saya tidak tahu sebagai default).

(Hai, saya mencoba membantu membuat masalah E-easy lebih mudah diakses oleh pendatang baru :smile_cat :)

Saya membuat laporan di atas menggunakan toolchain yang dikompilasi dengan pernyataan LLVM dinonaktifkan (yang saya tidak tahu sebagai default).

Sepertinya untuk mereproduksi masalah ini, Anda harus menggunakan rantai alat yang dikompilasi dengan pengaturan non-default? Jika demikian, bagaimana seseorang melakukannya?

Agak membingungkan apa yang seharusnya terjadi di sini, dengan semua hal penutupan-pembukaan kembali terjadi. Bisakah seseorang mengklarifikasi apa perilaku yang diharapkan dan bagaimana perbedaannya dari perilaku saat ini?

./configure --enable-llvm-assertions

Namun, Anda bisa menggunakan Rust nightly, karena pernyataan LLVM diaktifkan di sana. http://is.gd/X2RztV masih gagal dalam pernyataan di malam hari:

<anon>:2:17: 2:21 error: const index-expr is out of bounds
<anon>:2 static b: i32 = a[1];
                         ^~~~
rustc: /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::SequentialType; Y = llvm::Type; typename llvm::cast_retty<X, Y*>::ret_type = llvm::SequentialType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
Aborted (core dumped)
playpen: application terminated with error code 134

Sepertinya hal yang membuat saya tertekan pada tahun 2013 telah diperbaiki: jika rustc memberikan kesalahan const index-expr is out of bounds , bahkan jika pernyataan LLVM dinonaktifkan, ia keluar dengan status kegagalan (dan tidak menulis file keluaran). Saya pikir terjemahan dulu tidak memiliki akses ke sesi/kesalahan yang diperiksa, karena tidak seharusnya dapat menemukan kesalahan yang tidak diperiksa? Tapi sepertinya tidak demikian sekarang.

Hal lain yang saya sebutkan di masa lalu ... sepertinya kami dulu hanya meneruskan indeks ke LLVM meskipun kami tahu itu di luar jangkauan, tetapi sekarang kami membuat undef sebagai gantinya. Tapi bagian itu diurus dalam hal apapun, karena kesalahan ditangani dengan benar sekarang.

Adapun pernyataan LLVM yang kita lihat hari ini, saya punya tebakan. Setelah melaporkan kesalahan, kami melakukan ini:

C_undef(type_of::type_of(cx, bt).element_type())

dan saya pikir kami menginginkan sesuatu seperti ini (belum diuji):

C_undef(val_ty(arr).element_type())

Karena jika nilai yang diindeks adalah irisan atau pointer, maka bt (tipenya) tidak akan diwakili oleh tipe array, jadi element_type akan gagal.

Tapi , hal yang @graydon buka untuk masalah ini, dan apa yang disarankan oleh komentar dalam kode yang merujuk pada masalah ini, adalah memindahkan cek itu ke tahap kompilasi sebelumnya. Dan sepertinya #25370/#25570 mungkin akan berakhir kurang lebih mencapai itu?

Saya pikir ini sudah diperbaiki sepenuhnya sekarang. @oli-obk ?

tidak, itu perlu diselesaikan di check_const dan lokasi laporan saat ini perlu diubah menjadi lokasi bug

@oli-obk Apakah ini perbaikan yang mudah, dan jika demikian, apakah Anda ingin membimbingnya dan meninggalkan beberapa petunjuk sehingga pendatang baru dapat mencoba memecahkannya?

Meskipun ini adalah perbaikan yang mudah (pada dasarnya Anda dapat mencuri https://github.com/rust-lang/rust/blob/master/src/librustc/middle/check_const.rs#L470-L490 dan melakukannya untuk ExprIndex dan kemudian ubah https://github.com/rust-lang/rust/blob/master/src/librustc_trans/trans/consts.rs#L708-L712 menjadi bug/ unimplemented!() ).

Tapi itu juga akan menjadi perubahan yang mengganggu, karena const ARR: [u32; 0] = []; const X: u32 = ARR[5]; tidak digunakan saat ini tidak menyebabkan kesalahan kompilasi. Dan check_const juga memeriksa konstanta yang tidak digunakan.

Juga pada akhirnya akan melakukan semua evaluasi const dua kali. Yang bisa diperbaiki setelah menjadi masalah dengan caching konstanta.

Tentu saja perubahan yang rusak dapat diperbaiki hanya dengan memancarkan lint const_err .

ini tampaknya telah 'diselesaikan' (mungkin karena MIRI) karena sekarang melempar E0080 saat digunakan, daripada pernyataan LLVM. meskipun masih melewati jika akses tidak digunakan.

Serat yang hilang saat const tidak digunakan akan diperbaiki oleh https://github.com/rust-lang/rust/pull/50110

Ya saya pikir kita sudah selesai dengan masalah ini setelah 6 tahun :tertawa:

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

mcarton picture mcarton  ·  3Komentar

Robbepop picture Robbepop  ·  3Komentar

dnsl48 picture dnsl48  ·  3Komentar

SharplEr picture SharplEr  ·  3Komentar

pedrohjordao picture pedrohjordao  ·  3Komentar