Skip to content

Commit 2dd4d2a

Browse files
authored
Merge pull request rust-lang#125 from wasmerio/constantint
Add IntValue::is_constant_int() which is true iff is_const() and the int value is not a constant expression.
2 parents e4fc903 + 0861b69 commit 2dd4d2a

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/values/int_value.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use llvm_sys::core::{LLVMConstNot, LLVMConstNeg, LLVMConstNSWNeg, LLVMConstNUWNeg, LLVMConstAdd, LLVMConstNSWAdd, LLVMConstNUWAdd, LLVMConstSub, LLVMConstNSWSub, LLVMConstNUWSub, LLVMConstMul, LLVMConstNSWMul, LLVMConstNUWMul, LLVMConstUDiv, LLVMConstSDiv, LLVMConstSRem, LLVMConstURem, LLVMConstIntCast, LLVMConstXor, LLVMConstOr, LLVMConstAnd, LLVMConstExactSDiv, LLVMConstShl, LLVMConstLShr, LLVMConstAShr, LLVMConstUIToFP, LLVMConstSIToFP, LLVMConstIntToPtr, LLVMConstTrunc, LLVMConstSExt, LLVMConstZExt, LLVMConstTruncOrBitCast, LLVMConstSExtOrBitCast, LLVMConstZExtOrBitCast, LLVMConstBitCast, LLVMConstICmp, LLVMConstIntGetZExtValue, LLVMConstIntGetSExtValue, LLVMConstSelect};
1+
use llvm_sys::core::{LLVMConstNot, LLVMConstNeg, LLVMConstNSWNeg, LLVMConstNUWNeg, LLVMConstAdd, LLVMConstNSWAdd, LLVMConstNUWAdd, LLVMConstSub, LLVMConstNSWSub, LLVMConstNUWSub, LLVMConstMul, LLVMConstNSWMul, LLVMConstNUWMul, LLVMConstUDiv, LLVMConstSDiv, LLVMConstSRem, LLVMConstURem, LLVMConstIntCast, LLVMConstXor, LLVMConstOr, LLVMConstAnd, LLVMConstExactSDiv, LLVMConstShl, LLVMConstLShr, LLVMConstAShr, LLVMConstUIToFP, LLVMConstSIToFP, LLVMConstIntToPtr, LLVMConstTrunc, LLVMConstSExt, LLVMConstZExt, LLVMConstTruncOrBitCast, LLVMConstSExtOrBitCast, LLVMConstZExtOrBitCast, LLVMConstBitCast, LLVMConstICmp, LLVMConstIntGetZExtValue, LLVMConstIntGetSExtValue, LLVMConstSelect, LLVMIsAConstantInt};
22
#[llvm_versions(4.0..=latest)]
33
use llvm_sys::core::LLVMConstExactUDiv;
44
use llvm_sys::prelude::LLVMValueRef;
@@ -385,7 +385,10 @@ impl IntValue {
385385
BasicValueEnum::new(value)
386386
}
387387

388-
/// Determines whether or not an `IntValue` is a constant.
388+
/// Determines whether or not an `IntValue` is an `llvm::Constant`.
389+
///
390+
/// Constants includes values that are not known at compile time, for
391+
/// example the address of a function casted to an integer.
389392
///
390393
/// # Example
391394
///
@@ -402,6 +405,25 @@ impl IntValue {
402405
self.int_value.is_const()
403406
}
404407

408+
/// Determines whether or not an `IntValue` is an `llvm::ConstantInt`.
409+
///
410+
/// ConstantInt only includes values that are known at compile time.
411+
///
412+
/// # Example
413+
///
414+
/// ```no_run
415+
/// use inkwell::context::Context;
416+
///
417+
/// let context = Context::create();
418+
/// let i64_type = context.i64_type();
419+
/// let i64_val = i64_type.const_int(12, false);
420+
///
421+
/// assert!(i64_val.is_constant_int());
422+
/// ```
423+
pub fn is_constant_int(&self) -> bool {
424+
!unsafe { LLVMIsAConstantInt(self.as_value_ref()) }.is_null()
425+
}
426+
405427
/// Obtains a constant `IntValue`'s zero extended value.
406428
///
407429
/// # Example
@@ -417,7 +439,7 @@ impl IntValue {
417439
/// ```
418440
pub fn get_zero_extended_constant(&self) -> Option<u64> {
419441
// Garbage values are produced on non constant values
420-
if !self.is_const() {
442+
if !self.is_constant_int() {
421443
return None;
422444
}
423445
if self.get_type().get_bit_width() > 64 {
@@ -444,7 +466,7 @@ impl IntValue {
444466
/// ```
445467
pub fn get_sign_extended_constant(&self) -> Option<i64> {
446468
// Garbage values are produced on non constant values
447-
if !self.is_const() {
469+
if !self.is_constant_int() {
448470
return None;
449471
}
450472
if self.get_type().get_bit_width() > 64 {

tests/all/test_values.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1251,3 +1251,20 @@ fn test_aggregate_returns() {
12511251

12521252
assert!(module.verify().is_ok());
12531253
}
1254+
1255+
#[test]
1256+
fn test_constant_expression() {
1257+
let context = Context::create();
1258+
let builder = context.create_builder();
1259+
let module = context.create_module("my_mod");
1260+
1261+
let i32_type = context.i32_type();
1262+
let void_type = context.void_type();
1263+
let fn_type = void_type.fn_type(&[], false);
1264+
1265+
let function = module.add_function("", fn_type, None);
1266+
let expr = builder.build_ptr_to_int(function.as_global_value().as_pointer_value(), i32_type, "");
1267+
1268+
assert!(expr.is_const());
1269+
assert!(!expr.is_constant_int());
1270+
}

0 commit comments

Comments
 (0)