Skip to content

tuple struct constructors and uninitialized fields #96

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

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
tex/*/out
*.dot
*.mir
*.rs.bk
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ before_script:
- |
pip install 'travis-cargo<0.2' --user &&
export PATH=$HOME/.local/bin:$PATH
- sh ~/rust-installer/rustup.sh --add-target=i686-unknown-linux-gnu --prefix=/home/travis/rust -y --disable-sudo
- sh ~/rust-installer/rustup.sh --add-target=i686-pc-windows-gnu --prefix=/home/travis/rust -y --disable-sudo
- sh ~/rust-installer/rustup.sh --add-target=i686-pc-windows-msvc --prefix=/home/travis/rust p-y --disable-sudo
script:
- |
env RUST_SYSROOT=$HOME/rust travis-cargo build &&
Expand Down
40 changes: 20 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ test = false
test = false

[dependencies]
byteorder = "0.4.2"
#byteorder = "0.4.2"
byteorder = { git = "https://github.com/quininer/byteorder.git", branch = "i128", features = ["i128"]}
env_logger = "0.3.3"
log = "0.3.6"
log_settings = "0.1.1"
Expand Down
19 changes: 14 additions & 5 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(rustc_private)]
#![feature(rustc_private, i128_type)]

extern crate getopts;
extern crate miri;
Expand All @@ -21,7 +21,10 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
let mut control = CompileController::basic();
control.after_hir_lowering.callback = Box::new(after_hir_lowering);
control.after_analysis.callback = Box::new(after_analysis);
control.after_analysis.stop = Compilation::Stop;
if std::env::var("MIRI_HOST_TARGET") != Ok("yes".to_owned()) {
// only fully compile targets on the host
control.after_analysis.stop = Compilation::Stop;
}
control
}
}
Expand Down Expand Up @@ -51,7 +54,7 @@ fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits
let mut limits = miri::ResourceLimits::default();
let krate = state.hir_crate.as_ref().unwrap();
let err_msg = "miri attributes need to be in the form `miri(key = value)`";
let extract_int = |lit: &syntax::ast::Lit| -> u64 {
let extract_int = |lit: &syntax::ast::Lit| -> u128 {
match lit.node {
syntax::ast::LitKind::Int(i, _) => i,
_ => state.session.span_fatal(lit.span, "expected an integer literal"),
Expand All @@ -64,8 +67,8 @@ fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits
if let NestedMetaItemKind::MetaItem(ref inner) = item.node {
if let MetaItemKind::NameValue(ref value) = inner.node {
match &inner.name().as_str()[..] {
"memory_size" => limits.memory_size = extract_int(value),
"step_limit" => limits.step_limit = extract_int(value),
"memory_size" => limits.memory_size = extract_int(value) as u64,
"step_limit" => limits.step_limit = extract_int(value) as u64,
"stack_limit" => limits.stack_limit = extract_int(value) as usize,
_ => state.session.span_err(item.span, "unknown miri attribute"),
}
Expand Down Expand Up @@ -136,6 +139,12 @@ fn main() {
args.push(sysroot_flag);
args.push(find_sysroot());
}
// we run the optimization passes inside miri
// if we ran them twice we'd get funny failures due to borrowck ElaborateDrops only working on
// unoptimized MIR
// FIXME: add an after-mir-passes hook to rustc driver
args.push("-Zmir-opt-level=0".to_owned());
// for auxilary builds in unit tests
args.push("-Zalways-encode-mir".to_owned());

rustc_driver::run_compiler(&args, &mut MiriCompilerCalls, None, None);
Expand Down
40 changes: 21 additions & 19 deletions src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,36 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
F32 => self.cast_float(val.to_f32()? as f64, dest_ty),
F64 => self.cast_float(val.to_f64()?, dest_ty),

I8 | I16 | I32 | I64 => self.cast_signed_int(val.to_i64()?, dest_ty),
I8 | I16 | I32 | I64 | I128 => self.cast_signed_int(val.to_i128()?, dest_ty),

Bool | Char | U8 | U16 | U32 | U64 => self.cast_int(val.to_u64()?, dest_ty, false),
Bool | Char | U8 | U16 | U32 | U64 | U128 => self.cast_int(val.to_u128()?, dest_ty, false),

FnPtr | Ptr => self.cast_ptr(val.to_ptr()?, dest_ty),
}
}

fn cast_signed_int(&self, val: i64, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
self.cast_int(val as u64, ty, val < 0)
fn cast_signed_int(&self, val: i128, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
self.cast_int(val as u128, ty, val < 0)
}

fn cast_int(&self, v: u64, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
fn cast_int(&self, v: u128, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
use rustc::ty::TypeVariants::*;
match ty.sty {
TyBool if v == 0 => Ok(PrimVal::from_bool(false)),
TyBool if v == 1 => Ok(PrimVal::from_bool(true)),
TyBool => Err(EvalError::InvalidBool),

TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i64 as i8 as u64)),
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i64 as i16 as u64)),
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i64 as i32 as u64)),
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i64 as i64 as u64)),
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i128 as i8 as u128)),
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i128 as i64 as u128)),
TyInt(IntTy::I128) => Ok(PrimVal::Bytes(v as u128)),

TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u64)),
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u64)),
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u64)),
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v)),
TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u128)),
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),

TyInt(IntTy::Is) => {
let int_ty = self.tcx.sess.target.int_type;
Expand All @@ -61,15 +63,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
self.cast_int(v, ty, negative)
}

TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i64 as f64)),
TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i128 as f64)),
TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(v as f64)),
TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i64 as f32)),
TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i128 as f32)),
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(v as f32)),

TyChar if v as u8 as u64 == v => Ok(PrimVal::Bytes(v)),
TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
TyChar => Err(EvalError::InvalidChar(v)),

TyRawPtr(_) => Ok(PrimVal::Ptr(Pointer::from_int(v))),
TyRawPtr(_) => Ok(PrimVal::Ptr(Pointer::from_int(v as u64))),

_ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
}
Expand All @@ -80,9 +82,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
match ty.sty {
// Casting negative floats to unsigned integers yields zero.
TyUint(_) if val < 0.0 => self.cast_int(0, ty, false),
TyInt(_) if val < 0.0 => self.cast_int(val as i64 as u64, ty, true),
TyInt(_) if val < 0.0 => self.cast_int(val as i128 as u128, ty, true),

TyInt(_) | ty::TyUint(_) => self.cast_int(val as u64, ty, false),
TyInt(_) | ty::TyUint(_) => self.cast_int(val as u128, ty, false),

TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(val)),
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)),
Expand Down
13 changes: 12 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub enum EvalError<'tcx> {
ExecuteMemory,
ArrayIndexOutOfBounds(Span, u64, u64),
Math(Span, ConstMathErr),
InvalidChar(u64),
InvalidChar(u128),
OutOfMemory {
allocation_size: u64,
memory_size: u64,
Expand All @@ -52,6 +52,11 @@ pub enum EvalError<'tcx> {
ReallocatedFrozenMemory,
DeallocatedFrozenMemory,
Layout(layout::LayoutError<'tcx>),
Abort,
Panic {
file: String,
line: u32,
},
}

pub type EvalResult<'tcx, T> = Result<T, EvalError<'tcx>>;
Expand Down Expand Up @@ -122,6 +127,10 @@ impl<'tcx> Error for EvalError<'tcx> {
"rustc layout computation failed",
EvalError::UnterminatedCString(_) =>
"attempted to get length of a null terminated string, but no null found before end of allocation",
EvalError::Abort =>
"`abort` intrinsic reached",
EvalError::Panic { .. } =>
"panic!",
}
}

Expand Down Expand Up @@ -154,6 +163,8 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
write!(f, "expected primitive type, got {}", ty),
EvalError::Layout(ref err) =>
write!(f, "rustc layout computation failed: {:?}", err),
EvalError::Panic { ref file, line } =>
write!(f, "panicked at {}:{}", file, line),
_ => write!(f, "{}", self.description()),
}
}
Expand Down
Loading