diff --git a/src/macros.rs b/src/macros.rs index 2c988281ec..3cf348fe00 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,3 +1,6 @@ +// TODO: set this for entire crate when possible +#![deny(unsafe_op_in_unsafe_fn)] + /// Print to stdout #[macro_export] macro_rules! print { @@ -139,7 +142,9 @@ macro_rules! strto_impl { // const input but mut output, yet the man page says // "stores the address of the first invalid character in *endptr" // so obviously it doesn't want us to clone it. - *$endptr = $s.offset(idx) as *mut _; + unsafe { + *$endptr = $s.offset(idx) as *mut _; + } } }; @@ -157,12 +162,12 @@ macro_rules! strto_impl { let mut idx = 0; // skip any whitespace at the beginning of the string - while ctype::isspace(*$s.offset(idx) as c_int) != 0 { + while ctype::isspace(unsafe { *$s.offset(idx) } as c_int) != 0 { idx += 1; } // check for +/- - let positive = match is_positive(*$s.offset(idx)) { + let positive = match is_positive(unsafe { *$s.offset(idx) }) { Some((pos, i)) => { idx += i; pos @@ -174,15 +179,15 @@ macro_rules! strto_impl { }; // convert the string to a number - let num_str = $s.offset(idx); + let num_str = unsafe { $s.offset(idx) }; let res = match $base { - 0 => detect_base(num_str).and_then(|($base, i)| { + 0 => unsafe { detect_base(num_str) }.and_then(|($base, i)| { idx += i; - convert_integer(num_str.offset(i), $base) + unsafe { convert_integer(num_str.offset(i), $base) } }), - 8 => convert_octal(num_str), - 16 => convert_hex(num_str), - _ => convert_integer(num_str, $base), + 8 => unsafe { convert_octal(num_str) }, + 16 => unsafe { convert_hex(num_str) }, + _ => unsafe { convert_integer(num_str, $base) }, }; // check for error parsing octal/hex prefix @@ -231,86 +236,86 @@ macro_rules! strto_float_impl { let mut s = $s; let endptr = $endptr; - while ctype::isspace(*s as c_int) != 0 { - s = s.offset(1); + while ctype::isspace(unsafe{*s} as c_int) != 0 { + s = unsafe{ s.offset(1)}; } let mut result: $type = 0.0; let mut exponent: Option<$type> = None; let mut radix = 10; - let result_sign = match *s as u8 { + let result_sign = match unsafe{*s} as u8 { b'-' => { - s = s.offset(1); + s = unsafe{s.offset(1)}; -1.0 } b'+' => { - s = s.offset(1); + s = unsafe{s.offset(1)}; 1.0 } _ => 1.0, }; - let rust_s = CStr::from_ptr(s).to_string_lossy(); + let rust_s = unsafe{CStr::from_ptr(s)}.to_string_lossy(); // detect NaN, Inf if rust_s.to_lowercase().starts_with("inf") { result = $type::INFINITY; - s = s.offset(3); + s = unsafe{s.offset(3)}; } else if rust_s.to_lowercase().starts_with("nan") { // we cannot signal negative NaN in LLVM backed languages // https://github.com/rust-lang/rust/issues/73328 , https://github.com/rust-lang/rust/issues/81261 result = $type::NAN; - s = s.offset(3); + s = unsafe{s.offset(3)}; } else { - if *s as u8 == b'0' && *s.offset(1) as u8 == b'x' { - s = s.offset(2); + if unsafe{*s} as u8 == b'0' && unsafe{*s.offset(1)} as u8 == b'x' { + s = unsafe{s.offset(2)}; radix = 16; } - while let Some(digit) = (*s as u8 as char).to_digit(radix) { + while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) { result *= radix as $type; result += digit as $type; - s = s.offset(1); + s = unsafe{s.offset(1)}; } - if *s as u8 == b'.' { - s = s.offset(1); + if unsafe{*s} as u8 == b'.' { + s = unsafe{s.offset(1)}; let mut i = 1.0; - while let Some(digit) = (*s as u8 as char).to_digit(radix) { + while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) { i *= radix as $type; result += digit as $type / i; - s = s.offset(1); + s = unsafe{s.offset(1)}; } } let s_before_exponent = s; - exponent = match (*s as u8, radix) { + exponent = match (unsafe{*s} as u8, radix) { (b'e' | b'E', 10) | (b'p' | b'P', 16) => { - s = s.offset(1); + s = unsafe{s.offset(1)}; - let is_exponent_positive = match *s as u8 { + let is_exponent_positive = match unsafe{*s} as u8 { b'-' => { - s = s.offset(1); + s = unsafe{s.offset(1)}; false } b'+' => { - s = s.offset(1); + s = unsafe{s.offset(1)}; true } _ => true, }; // Exponent digits are always in base 10. - if (*s as u8 as char).is_digit(10) { + if (unsafe{*s} as u8 as char).is_digit(10) { let mut exponent_value = 0; - while let Some(digit) = (*s as u8 as char).to_digit(10) { + while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(10) { exponent_value *= 10; exponent_value += digit; - s = s.offset(1); + s = unsafe{s.offset(1)}; } let exponent_base = match radix { @@ -339,7 +344,7 @@ macro_rules! strto_float_impl { // const input but mut output, yet the man page says // "stores the address of the first invalid character in *endptr" // so obviously it doesn't want us to clone it. - *endptr = s as *mut _; + unsafe{*endptr = s as *mut _}; } if let Some(exponent) = exponent {