summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-09-04 08:26:52 -0400
committerGitHub <noreply@github.com>2018-09-04 08:26:52 -0400
commit36c087bb4a22ae37d96a7a711293f5ee2d98015f (patch)
treee393ffaf062cc1c62becfe0053aeb37e62fa58d9
parent0db9588e84463c211340f0bc2cb6da2b3a99c441 (diff)
parent2319708814878e7b102b5223fa762e0f464a3f96 (diff)
Auto merge of #1381 - emilio:integer-eval, r=noxv0.40.0
ir: Handle overflowing integer constant evaluation properly. Fixes #1380
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/clang.rs33
-rw-r--r--src/ir/var.rs3
-rw-r--r--tests/expectations/tests/derive-debug-bitfield-core.rs2
-rw-r--r--tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs7
-rw-r--r--tests/expectations/tests/libclang-3.8/constant-evaluate.rs4
-rw-r--r--tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs10
-rw-r--r--tests/expectations/tests/libclang-3.9/constant-evaluate.rs4
-rw-r--r--tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs10
-rw-r--r--tests/expectations/tests/libclang-4/constant-evaluate.rs10
-rw-r--r--tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs10
-rw-r--r--tests/expectations/tests/libclang-5/constant-evaluate.rs10
-rw-r--r--tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs10
-rw-r--r--tests/headers/constant-evaluate.h1
-rw-r--r--tests/headers/derive-debug-bitfield-core.hpp2
16 files changed, 98 insertions, 22 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d642aeb1..e510cc8c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -23,7 +23,7 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.39.0"
+version = "0.40.0"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 9e7d3268..61dbe3d9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@ readme = "README.md"
repository = "https://github.com/rust-lang-nursery/rust-bindgen"
documentation = "https://docs.rs/bindgen"
homepage = "https://rust-lang-nursery.github.io/rust-bindgen/"
-version = "0.39.0"
+version = "0.40.0"
build = "build.rs"
include = [
diff --git a/src/clang.rs b/src/clang.rs
index bac29ee3..78bbd07c 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -12,7 +12,7 @@ use std::ffi::{CStr, CString};
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
-use std::os::raw::{c_char, c_int, c_uint, c_ulong};
+use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_longlong, c_ulonglong};
/// A cursor into the Clang AST, pointing to an AST node.
///
@@ -1786,13 +1786,34 @@ impl EvalResult {
}
/// Try to get back the result as an integer.
- pub fn as_int(&self) -> Option<i32> {
- match self.kind() {
- CXEval_Int => {
- Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i32)
+ pub fn as_int(&self) -> Option<i64> {
+ if self.kind() != CXEval_Int {
+ return None;
+ }
+
+ if !clang_EvalResult_isUnsignedInt::is_loaded() {
+ // FIXME(emilio): There's no way to detect underflow here, and clang
+ // will just happily give us a value.
+ return Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i64)
+ }
+
+ if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 {
+ let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) };
+ if value > i64::max_value() as c_ulonglong {
+ return None;
}
- _ => None,
+
+ return Some(value as i64)
+ }
+
+ let value = unsafe { clang_EvalResult_getAsLongLong(self.x) };
+ if value > i64::max_value() as c_longlong {
+ return None;
+ }
+ if value < i64::min_value() as c_longlong {
+ return None;
}
+ Some(value as i64)
}
/// Evaluates the expression as a literal string, that may or may not be
diff --git a/src/ir/var.rs b/src/ir/var.rs
index 25ac56d2..78455c9b 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -265,8 +265,7 @@ impl ClangSubItemParser for Var {
let mut val = cursor
.evaluate()
- .and_then(|v| v.as_int())
- .map(|val| val as i64);
+ .and_then(|v| v.as_int());
if val.is_none() || !kind.signedness_matches(val.unwrap()) {
let tu = ctx.translation_unit();
val = get_integer_literal_from_cursor(&cursor, tu);
diff --git a/tests/expectations/tests/derive-debug-bitfield-core.rs b/tests/expectations/tests/derive-debug-bitfield-core.rs
index 11522bcb..8c47fce0 100644
--- a/tests/expectations/tests/derive-debug-bitfield-core.rs
+++ b/tests/expectations/tests/derive-debug-bitfield-core.rs
@@ -7,6 +7,8 @@
non_upper_case_globals
)]
+extern crate core;
+
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
diff --git a/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs
deleted file mode 100644
index 9613a7f2..00000000
--- a/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-/* automatically generated by rust-bindgen */
-
-
-#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
-
-pub const a: u32 = 18446744073709551611;
diff --git a/tests/expectations/tests/libclang-3.8/constant-evaluate.rs b/tests/expectations/tests/libclang-3.8/constant-evaluate.rs
index 8faddfe9..7df4e918 100644
--- a/tests/expectations/tests/libclang-3.8/constant-evaluate.rs
+++ b/tests/expectations/tests/libclang-3.8/constant-evaluate.rs
@@ -16,6 +16,10 @@ extern "C" {
pub static mut k_expr: EasyToOverflow;
}
extern "C" {
+ #[link_name = "\u{1}wow"]
+ pub static mut wow: EasyToOverflow;
+}
+extern "C" {
#[link_name = "\u{1}BAZ"]
pub static mut BAZ: ::std::os::raw::c_longlong;
}
diff --git a/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs
new file mode 100644
index 00000000..68eab7a2
--- /dev/null
+++ b/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub const a: u32 = 18446744073709551611;
diff --git a/tests/expectations/tests/libclang-3.9/constant-evaluate.rs b/tests/expectations/tests/libclang-3.9/constant-evaluate.rs
index 159dba7c..69501c64 100644
--- a/tests/expectations/tests/libclang-3.9/constant-evaluate.rs
+++ b/tests/expectations/tests/libclang-3.9/constant-evaluate.rs
@@ -15,6 +15,10 @@ pub enum _bindgen_ty_1 {
pub type EasyToOverflow = ::std::os::raw::c_ulonglong;
pub const k: EasyToOverflow = 2147483648;
pub const k_expr: EasyToOverflow = 0;
+extern "C" {
+ #[link_name = "\u{1}wow"]
+ pub static mut wow: EasyToOverflow;
+}
pub const BAZ: ::std::os::raw::c_longlong = 24;
pub const fuzz: f64 = 51.0;
pub const BAZZ: ::std::os::raw::c_char = 53;
diff --git a/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs
new file mode 100644
index 00000000..68eab7a2
--- /dev/null
+++ b/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub const a: u32 = 18446744073709551611;
diff --git a/tests/expectations/tests/libclang-4/constant-evaluate.rs b/tests/expectations/tests/libclang-4/constant-evaluate.rs
index 045710f9..07df8114 100644
--- a/tests/expectations/tests/libclang-4/constant-evaluate.rs
+++ b/tests/expectations/tests/libclang-4/constant-evaluate.rs
@@ -1,6 +1,11 @@
/* automatically generated by rust-bindgen */
-#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo;
pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar;
@@ -12,7 +17,8 @@ pub enum _bindgen_ty_1 {
}
pub type EasyToOverflow = ::std::os::raw::c_ulonglong;
pub const k: EasyToOverflow = 2147483648;
-pub const k_expr: EasyToOverflow = 0;
+pub const k_expr: EasyToOverflow = 1152921504606846976;
+pub const wow: EasyToOverflow = 2147483648;
pub const BAZ: ::std::os::raw::c_longlong = 24;
pub const fuzz: f64 = 51.0;
pub const BAZZ: ::std::os::raw::c_char = 53;
diff --git a/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs
new file mode 100644
index 00000000..7ad2fc1c
--- /dev/null
+++ b/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub const a: u32 = 4294967291;
diff --git a/tests/expectations/tests/libclang-5/constant-evaluate.rs b/tests/expectations/tests/libclang-5/constant-evaluate.rs
index 045710f9..07df8114 100644
--- a/tests/expectations/tests/libclang-5/constant-evaluate.rs
+++ b/tests/expectations/tests/libclang-5/constant-evaluate.rs
@@ -1,6 +1,11 @@
/* automatically generated by rust-bindgen */
-#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo;
pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar;
@@ -12,7 +17,8 @@ pub enum _bindgen_ty_1 {
}
pub type EasyToOverflow = ::std::os::raw::c_ulonglong;
pub const k: EasyToOverflow = 2147483648;
-pub const k_expr: EasyToOverflow = 0;
+pub const k_expr: EasyToOverflow = 1152921504606846976;
+pub const wow: EasyToOverflow = 2147483648;
pub const BAZ: ::std::os::raw::c_longlong = 24;
pub const fuzz: f64 = 51.0;
pub const BAZZ: ::std::os::raw::c_char = 53;
diff --git a/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs
new file mode 100644
index 00000000..7ad2fc1c
--- /dev/null
+++ b/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs
@@ -0,0 +1,10 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub const a: u32 = 4294967291;
diff --git a/tests/headers/constant-evaluate.h b/tests/headers/constant-evaluate.h
index e8d0a5ba..812553ed 100644
--- a/tests/headers/constant-evaluate.h
+++ b/tests/headers/constant-evaluate.h
@@ -10,6 +10,7 @@ typedef unsigned long long EasyToOverflow;
const EasyToOverflow k = 0x80000000;
const EasyToOverflow k_expr = 1ULL << 60;
+const EasyToOverflow wow = 1ULL << 31;
const long long BAZ = (1 << foo) | bar;
const double fuzz = (1 + 50.0f);
diff --git a/tests/headers/derive-debug-bitfield-core.hpp b/tests/headers/derive-debug-bitfield-core.hpp
index 7a5694ec..5d78e743 100644
--- a/tests/headers/derive-debug-bitfield-core.hpp
+++ b/tests/headers/derive-debug-bitfield-core.hpp
@@ -1,4 +1,4 @@
-// bindgen-flags: --impl-debug --use-core
+// bindgen-flags: --impl-debug --use-core --raw-line "extern crate core;"
class C {
bool a: 1;