diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-09-04 08:26:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-04 08:26:52 -0400 |
commit | 36c087bb4a22ae37d96a7a711293f5ee2d98015f (patch) | |
tree | e393ffaf062cc1c62becfe0053aeb37e62fa58d9 /src/clang.rs | |
parent | 0db9588e84463c211340f0bc2cb6da2b3a99c441 (diff) | |
parent | 2319708814878e7b102b5223fa762e0f464a3f96 (diff) |
Auto merge of #1381 - emilio:integer-eval, r=noxv0.40.0
ir: Handle overflowing integer constant evaluation properly.
Fixes #1380
Diffstat (limited to 'src/clang.rs')
-rw-r--r-- | src/clang.rs | 33 |
1 files changed, 27 insertions, 6 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 |