Skip to content

Commit f099e8c

Browse files
committed
Make set/get_volatile check the type of value.
1 parent da3760a commit f099e8c

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

Diff for: src/values/instruction_value.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,31 @@ impl InstructionValue {
184184

185185
// SubTypes: Only apply to memory access instructions
186186
/// Returns whether or not a memory access instruction is volatile.
187-
pub fn get_volatile(&self) -> bool {
187+
pub fn get_volatile(&self) -> Result<bool, &'static str> {
188+
let value_ref = self.as_value_ref();
188189
unsafe {
189-
LLVMGetVolatile(self.as_value_ref()) == 1
190+
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
191+
// does not export that functionality.
192+
if LLVMIsALoadInst(value_ref).is_null() &&
193+
LLVMIsAStoreInst(value_ref).is_null() {
194+
return Err("Value is not a load or store.");
195+
}
196+
Ok(LLVMGetVolatile(value_ref) == 1)
190197
}
191198
}
192199

193200
// SubTypes: Only apply to memory access instructions
194201
/// Sets whether or not a memory access instruction is volatile.
195-
pub fn set_volatile(&self, volatile: bool) {
202+
pub fn set_volatile(&self, volatile: bool) -> Result<(), &'static str> {
203+
let value_ref = self.as_value_ref();
196204
unsafe {
197-
LLVMSetVolatile(self.as_value_ref(), volatile as i32)
205+
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
206+
// does not export that functionality.
207+
if LLVMIsALoadInst(value_ref).is_null() &&
208+
LLVMIsAStoreInst(value_ref).is_null() {
209+
return Err("Value is not a load or store.");
210+
}
211+
Ok(LLVMSetVolatile(value_ref, volatile as i32))
198212
}
199213
}
200214

Diff for: tests/all/test_instruction_values.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -279,16 +279,16 @@ fn test_mem_instructions() {
279279
let load = builder.build_load(arg1, "");
280280
let load_instruction = load.as_instruction_value().unwrap();
281281

282-
assert_eq!(store_instruction.get_volatile(), false);
283-
assert_eq!(load_instruction.get_volatile(), false);
284-
store_instruction.set_volatile(true);
285-
load_instruction.set_volatile(true);
286-
assert_eq!(store_instruction.get_volatile(), true);
287-
assert_eq!(load_instruction.get_volatile(), true);
288-
store_instruction.set_volatile(false);
289-
load_instruction.set_volatile(false);
290-
assert_eq!(store_instruction.get_volatile(), false);
291-
assert_eq!(load_instruction.get_volatile(), false);
282+
assert_eq!(store_instruction.get_volatile().unwrap(), false);
283+
assert_eq!(load_instruction.get_volatile().unwrap(), false);
284+
store_instruction.set_volatile(true).unwrap();
285+
load_instruction.set_volatile(true).unwrap();
286+
assert_eq!(store_instruction.get_volatile().unwrap(), true);
287+
assert_eq!(load_instruction.get_volatile().unwrap(), true);
288+
store_instruction.set_volatile(false).unwrap();
289+
load_instruction.set_volatile(false).unwrap();
290+
assert_eq!(store_instruction.get_volatile().unwrap(), false);
291+
assert_eq!(load_instruction.get_volatile().unwrap(), false);
292292

293293
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
294294
assert_eq!(load_instruction.get_alignment().unwrap(), 0);
@@ -305,6 +305,8 @@ fn test_mem_instructions() {
305305
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
306306

307307
let fadd_instruction = builder.build_float_add(load.into_float_value(), f32_val, "").as_instruction_value().unwrap();
308+
assert!(fadd_instruction.get_volatile().is_err());
309+
assert!(fadd_instruction.set_volatile(false).is_err());
308310
assert!(fadd_instruction.get_alignment().is_err());
309311
assert!(fadd_instruction.set_alignment(16).is_err());
310312
}

0 commit comments

Comments
 (0)