From b37a98fa31f37e60206b7a8144407b7be71617ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 13 Nov 2016 12:57:54 +0100 Subject: [PATCH 1/2] expr: Handle correctly the minimum value of integers. --- src/expr.rs | 66 +++++++++++++++++----------------------------- src/lit.rs | 34 ++++++++++-------------- tests/test_expr.rs | 3 +++ 3 files changed, 41 insertions(+), 62 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index c1a148e54..43fff1efa 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -34,6 +34,20 @@ impl ExprBuilder { } } +macro_rules! signed_int_method { + ($ty:ident, $unsigned:ident) => { + pub fn $ty(self, val: $ty) -> F::Result { + if val == ::std::$ty::MIN { + self.neg().lit().$ty(val as $unsigned) + } else if val < 0 { + self.neg().lit().$ty(-val as $unsigned) + } else { + self.lit().$ty(val as $unsigned) + } + } + }; +} + impl ExprBuilder where F: Invoke>, { @@ -118,10 +132,12 @@ impl ExprBuilder } pub fn int(self, value: i64) -> F::Result { - if value < 0 { - self.neg().lit().int(-value) + if value == ::std::i64::MIN { + self.neg().lit().int(value as u64) + } else if value < 0 { + self.neg().lit().int(-value as u64) } else { - self.lit().int(value) + self.lit().int(value as u64) } } @@ -129,45 +145,11 @@ impl ExprBuilder self.lit().uint(value as u64) } - pub fn isize(self, value: isize) -> F::Result { - if value < 0 { - self.neg().lit().isize(-value) - } else { - self.lit().isize(value) - } - } - - pub fn i8(self, value: i8) -> F::Result { - if value < 0 { - self.neg().lit().i8(-value) - } else { - self.lit().i8(value) - } - } - - pub fn i16(self, value: i16) -> F::Result { - if value < 0 { - self.neg().lit().i16(-value) - } else { - self.lit().i16(value) - } - } - - pub fn i32(self, value: i32) -> F::Result { - if value < 0 { - self.neg().lit().i32(-value) - } else { - self.lit().i32(value) - } - } - - pub fn i64(self, value: i64) -> F::Result { - if value < 0 { - self.neg().lit().i64(-value) - } else { - self.lit().i64(value) - } - } + signed_int_method!(i8, u8); + signed_int_method!(i16, u16); + signed_int_method!(i32, u32); + signed_int_method!(i64, u64); + signed_int_method!(isize, usize); pub fn usize(self, value: usize) -> F::Result { self.lit().usize(value) diff --git a/src/lit.rs b/src/lit.rs index c317016c6..62f5371f4 100644 --- a/src/lit.rs +++ b/src/lit.rs @@ -56,38 +56,32 @@ impl LitBuilder self.bool(false) } - pub fn int(self, value: i64) -> F::Result { - assert!(value >= 0); - self.build_lit(ast::LitKind::Int(value as u64, ast::LitIntType::Unsuffixed)) + pub fn int(self, value: u64) -> F::Result { + self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsuffixed)) } - fn build_int(self, value: i64, ty: ast::IntTy) -> F::Result { - assert!(value >= 0); - self.build_lit(ast::LitKind::Int(value as u64, ast::LitIntType::Signed(ty))) + fn build_int(self, value: u64, ty: ast::IntTy) -> F::Result { + self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Signed(ty))) } - pub fn isize(self, value: isize) -> F::Result { - self.build_int(value as i64, ast::IntTy::Is) + pub fn isize(self, value: usize) -> F::Result { + self.build_int(value as u64, ast::IntTy::Is) } - pub fn i8(self, value: i8) -> F::Result { - assert!(value >= 0); - self.build_int(value as i64, ast::IntTy::I8) + pub fn i8(self, value: u8) -> F::Result { + self.build_int(value as u64, ast::IntTy::I8) } - pub fn i16(self, value: i16) -> F::Result { - assert!(value >= 0); - self.build_int(value as i64, ast::IntTy::I16) + pub fn i16(self, value: u16) -> F::Result { + self.build_int(value as u64, ast::IntTy::I16) } - pub fn i32(self, value: i32) -> F::Result { - assert!(value >= 0); - self.build_int(value as i64, ast::IntTy::I32) + pub fn i32(self, value: u32) -> F::Result { + self.build_int(value as u64, ast::IntTy::I32) } - pub fn i64(self, value: i64) -> F::Result { - assert!(value >= 0); - self.build_int(value, ast::IntTy::I64) + pub fn i64(self, value: u64) -> F::Result { + self.build_int(value as u64, ast::IntTy::I64) } pub fn uint(self, value: u64) -> F::Result { diff --git a/tests/test_expr.rs b/tests/test_expr.rs index 90a3442fc..34fca62ec 100644 --- a/tests/test_expr.rs +++ b/tests/test_expr.rs @@ -39,6 +39,9 @@ fn test_lit() { check(builder.expr().u64(5), builder.lit().u64(5)); check(builder.expr().usize(5), builder.lit().usize(5)); + // Doesn't crash. + assert_eq!(builder.expr().i64(::std::i64::MIN), + builder.expr().neg().lit().i64(1 << 63)); check(builder.expr().str("string"), builder.lit().str("string")); } From 4d5fcf7c8d957777f474ad29e2298cec592f9417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 13 Nov 2016 13:05:04 +0100 Subject: [PATCH 2/2] Breaking bump. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 15e462f3d..2b279765e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aster" -version = "0.33.1" +version = "0.34.0" authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "A libsyntax ast builder"