summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clang.rs33
-rw-r--r--src/ir/var.rs3
-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
12 files changed, 93 insertions, 19 deletions
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/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);