summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci/script.sh2
-rw-r--r--tests/expectations/tests/issue-816.rs808
-rw-r--r--tests/headers/issue-816.h49
-rw-r--r--tests/quickchecking/Cargo.toml14
-rw-r--r--tests/quickchecking/src/bin.rs110
-rw-r--r--tests/quickchecking/src/lib.rs98
-rw-r--r--tests/quickchecking/tests/fuzzed-c-headers.rs151
7 files changed, 1162 insertions, 70 deletions
diff --git a/ci/script.sh b/ci/script.sh
index b9e75892..91ea7c13 100755
--- a/ci/script.sh
+++ b/ci/script.sh
@@ -41,7 +41,7 @@ case "$BINDGEN_JOB" in
"quickchecking")
cd ./tests/quickchecking
# TODO: Actually run quickchecks once `bindgen` is reliable enough.
- cargo check
+ cargo test
;;
*)
echo "Error! Unknown \$BINDGEN_JOB: '$BINDGEN_JOB'"
diff --git a/tests/expectations/tests/issue-816.rs b/tests/expectations/tests/issue-816.rs
new file mode 100644
index 00000000..bb8a323a
--- /dev/null
+++ b/tests/expectations/tests/issue-816.rs
@@ -0,0 +1,808 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct __BindgenBitfieldUnit<Storage, Align>
+where
+ Storage: AsRef<[u8]> + AsMut<[u8]>,
+{
+ storage: Storage,
+ align: [Align; 0],
+}
+
+impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
+where
+ Storage: AsRef<[u8]> + AsMut<[u8]>,
+{
+ #[inline]
+ pub fn new(storage: Storage) -> Self {
+ Self { storage, align: [] }
+ }
+
+ #[inline]
+ pub fn get_bit(&self, index: usize) -> bool {
+ debug_assert!(index / 8 < self.storage.as_ref().len());
+
+ let byte_index = index / 8;
+ let byte = self.storage.as_ref()[byte_index];
+
+ let bit_index = index % 8;
+ let mask = 1 << bit_index;
+
+ byte & mask == mask
+ }
+
+ #[inline]
+ pub fn set_bit(&mut self, index: usize, val: bool) {
+ debug_assert!(index / 8 < self.storage.as_ref().len());
+
+ let byte_index = index / 8;
+ let byte = &mut self.storage.as_mut()[byte_index];
+
+ let bit_index = index % 8;
+ let mask = 1 << bit_index;
+
+ if val {
+ *byte |= mask;
+ } else {
+ *byte &= !mask;
+ }
+ }
+
+ #[inline]
+ pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
+ debug_assert!(bit_width <= 64);
+ debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
+ debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
+
+ let mut val = 0;
+
+ for i in 0..(bit_width as usize) {
+ if self.get_bit(i + bit_offset) {
+ val |= 1 << i;
+ }
+ }
+
+ val
+ }
+
+ #[inline]
+ pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
+ debug_assert!(bit_width <= 64);
+ debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
+ debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
+
+ for i in 0..(bit_width as usize) {
+ let mask = 1 << i;
+ let val_bit_is_set = val & mask == mask;
+ self.set_bit(i + bit_offset, val_bit_is_set);
+ }
+ }
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct jvmtiCapabilities {
+ pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize], u8>,
+ pub __bindgen_align: [u32; 0usize],
+}
+#[test]
+fn bindgen_test_layout_jvmtiCapabilities() {
+ assert_eq!(
+ ::std::mem::size_of::<jvmtiCapabilities>(),
+ 16usize,
+ concat!("Size of: ", stringify!(jvmtiCapabilities))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<jvmtiCapabilities>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(jvmtiCapabilities))
+ );
+}
+impl jvmtiCapabilities {
+ #[inline]
+ pub fn can_tag_objects(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_tag_objects(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(0usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_field_modification_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_field_modification_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(1usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_field_access_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_field_access_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(2usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_bytecodes(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_bytecodes(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(3usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_synthetic_attribute(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_synthetic_attribute(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(4usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_owned_monitor_info(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_owned_monitor_info(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(5usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_current_contended_monitor(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_current_contended_monitor(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(6usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_monitor_info(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_monitor_info(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(7usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_pop_frame(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_pop_frame(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(8usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_redefine_classes(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_redefine_classes(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(9usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_signal_thread(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_signal_thread(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(10usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_source_file_name(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_source_file_name(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(11usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_line_numbers(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_line_numbers(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(12usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_source_debug_extension(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_source_debug_extension(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(13usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_access_local_variables(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_access_local_variables(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(14usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_maintain_original_method_order(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_maintain_original_method_order(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(15usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_single_step_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_single_step_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(16usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_exception_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_exception_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(17usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_frame_pop_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_frame_pop_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(18usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_breakpoint_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_breakpoint_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(19usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_suspend(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_suspend(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(20usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_redefine_any_class(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_redefine_any_class(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(21usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_current_thread_cpu_time(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_current_thread_cpu_time(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(22usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_thread_cpu_time(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_thread_cpu_time(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(23usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_method_entry_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_method_entry_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(24usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_method_exit_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_method_exit_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(25usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_all_class_hook_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_all_class_hook_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(26usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_compiled_method_load_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_compiled_method_load_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(27usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_monitor_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_monitor_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(28usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_vm_object_alloc_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_vm_object_alloc_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(29usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_native_method_bind_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_native_method_bind_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(30usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_garbage_collection_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_garbage_collection_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(31usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_object_free_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_object_free_events(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(32usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_force_early_return(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(33usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_force_early_return(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(33usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_owned_monitor_stack_depth_info(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(34usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_owned_monitor_stack_depth_info(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(34usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_get_constant_pool(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(35usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_get_constant_pool(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(35usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_set_native_method_prefix(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(36usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_set_native_method_prefix(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(36usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_retransform_classes(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(37usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_retransform_classes(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(37usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_retransform_any_class(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(38usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_retransform_any_class(&mut self, val: ::std::os::raw::c_uint) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(38usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_resource_exhaustion_heap_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(39usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_resource_exhaustion_heap_events(
+ &mut self,
+ val: ::std::os::raw::c_uint,
+ ) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(39usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn can_generate_resource_exhaustion_threads_events(&self) -> ::std::os::raw::c_uint {
+ unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 1u8) as u32) }
+ }
+ #[inline]
+ pub fn set_can_generate_resource_exhaustion_threads_events(
+ &mut self,
+ val: ::std::os::raw::c_uint,
+ ) {
+ unsafe {
+ let val: u32 = ::std::mem::transmute(val);
+ self._bitfield_1.set(40usize, 1u8, val as u64)
+ }
+ }
+ #[inline]
+ pub fn new_bitfield_1(
+ can_tag_objects: ::std::os::raw::c_uint,
+ can_generate_field_modification_events: ::std::os::raw::c_uint,
+ can_generate_field_access_events: ::std::os::raw::c_uint,
+ can_get_bytecodes: ::std::os::raw::c_uint,
+ can_get_synthetic_attribute: ::std::os::raw::c_uint,
+ can_get_owned_monitor_info: ::std::os::raw::c_uint,
+ can_get_current_contended_monitor: ::std::os::raw::c_uint,
+ can_get_monitor_info: ::std::os::raw::c_uint,
+ can_pop_frame: ::std::os::raw::c_uint,
+ can_redefine_classes: ::std::os::raw::c_uint,
+ can_signal_thread: ::std::os::raw::c_uint,
+ can_get_source_file_name: ::std::os::raw::c_uint,
+ can_get_line_numbers: ::std::os::raw::c_uint,
+ can_get_source_debug_extension: ::std::os::raw::c_uint,
+ can_access_local_variables: ::std::os::raw::c_uint,
+ can_maintain_original_method_order: ::std::os::raw::c_uint,
+ can_generate_single_step_events: ::std::os::raw::c_uint,
+ can_generate_exception_events: ::std::os::raw::c_uint,
+ can_generate_frame_pop_events: ::std::os::raw::c_uint,
+ can_generate_breakpoint_events: ::std::os::raw::c_uint,
+ can_suspend: ::std::os::raw::c_uint,
+ can_redefine_any_class: ::std::os::raw::c_uint,
+ can_get_current_thread_cpu_time: ::std::os::raw::c_uint,
+ can_get_thread_cpu_time: ::std::os::raw::c_uint,
+ can_generate_method_entry_events: ::std::os::raw::c_uint,
+ can_generate_method_exit_events: ::std::os::raw::c_uint,
+ can_generate_all_class_hook_events: ::std::os::raw::c_uint,
+ can_generate_compiled_method_load_events: ::std::os::raw::c_uint,
+ can_generate_monitor_events: ::std::os::raw::c_uint,
+ can_generate_vm_object_alloc_events: ::std::os::raw::c_uint,
+ can_generate_native_method_bind_events: ::std::os::raw::c_uint,
+ can_generate_garbage_collection_events: ::std::os::raw::c_uint,
+ can_generate_object_free_events: ::std::os::raw::c_uint,
+ can_force_early_return: ::std::os::raw::c_uint,
+ can_get_owned_monitor_stack_depth_info: ::std::os::raw::c_uint,
+ can_get_constant_pool: ::std::os::raw::c_uint,
+ can_set_native_method_prefix: ::std::os::raw::c_uint,
+ can_retransform_classes: ::std::os::raw::c_uint,
+ can_retransform_any_class: ::std::os::raw::c_uint,
+ can_generate_resource_exhaustion_heap_events: ::std::os::raw::c_uint,
+ can_generate_resource_exhaustion_threads_events: ::std::os::raw::c_uint,
+ ) -> __BindgenBitfieldUnit<[u8; 16usize], u8> {
+ let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize], u8> =
+ Default::default();
+ __bindgen_bitfield_unit.set(0usize, 1u8, {
+ let can_tag_objects: u32 = unsafe { ::std::mem::transmute(can_tag_objects) };
+ can_tag_objects as u64
+ });
+ __bindgen_bitfield_unit.set(1usize, 1u8, {
+ let can_generate_field_modification_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_field_modification_events) };
+ can_generate_field_modification_events as u64
+ });
+ __bindgen_bitfield_unit.set(2usize, 1u8, {
+ let can_generate_field_access_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_field_access_events) };
+ can_generate_field_access_events as u64
+ });
+ __bindgen_bitfield_unit.set(3usize, 1u8, {
+ let can_get_bytecodes: u32 = unsafe { ::std::mem::transmute(can_get_bytecodes) };
+ can_get_bytecodes as u64
+ });
+ __bindgen_bitfield_unit.set(4usize, 1u8, {
+ let can_get_synthetic_attribute: u32 =
+ unsafe { ::std::mem::transmute(can_get_synthetic_attribute) };
+ can_get_synthetic_attribute as u64
+ });
+ __bindgen_bitfield_unit.set(5usize, 1u8, {
+ let can_get_owned_monitor_info: u32 =
+ unsafe { ::std::mem::transmute(can_get_owned_monitor_info) };
+ can_get_owned_monitor_info as u64
+ });
+ __bindgen_bitfield_unit.set(6usize, 1u8, {
+ let can_get_current_contended_monitor: u32 =
+ unsafe { ::std::mem::transmute(can_get_current_contended_monitor) };
+ can_get_current_contended_monitor as u64
+ });
+ __bindgen_bitfield_unit.set(7usize, 1u8, {
+ let can_get_monitor_info: u32 = unsafe { ::std::mem::transmute(can_get_monitor_info) };
+ can_get_monitor_info as u64
+ });
+ __bindgen_bitfield_unit.set(8usize, 1u8, {
+ let can_pop_frame: u32 = unsafe { ::std::mem::transmute(can_pop_frame) };
+ can_pop_frame as u64
+ });
+ __bindgen_bitfield_unit.set(9usize, 1u8, {
+ let can_redefine_classes: u32 = unsafe { ::std::mem::transmute(can_redefine_classes) };
+ can_redefine_classes as u64
+ });
+ __bindgen_bitfield_unit.set(10usize, 1u8, {
+ let can_signal_thread: u32 = unsafe { ::std::mem::transmute(can_signal_thread) };
+ can_signal_thread as u64
+ });
+ __bindgen_bitfield_unit.set(11usize, 1u8, {
+ let can_get_source_file_name: u32 =
+ unsafe { ::std::mem::transmute(can_get_source_file_name) };
+ can_get_source_file_name as u64
+ });
+ __bindgen_bitfield_unit.set(12usize, 1u8, {
+ let can_get_line_numbers: u32 = unsafe { ::std::mem::transmute(can_get_line_numbers) };
+ can_get_line_numbers as u64
+ });
+ __bindgen_bitfield_unit.set(13usize, 1u8, {
+ let can_get_source_debug_extension: u32 =
+ unsafe { ::std::mem::transmute(can_get_source_debug_extension) };
+ can_get_source_debug_extension as u64
+ });
+ __bindgen_bitfield_unit.set(14usize, 1u8, {
+ let can_access_local_variables: u32 =
+ unsafe { ::std::mem::transmute(can_access_local_variables) };
+ can_access_local_variables as u64
+ });
+ __bindgen_bitfield_unit.set(15usize, 1u8, {
+ let can_maintain_original_method_order: u32 =
+ unsafe { ::std::mem::transmute(can_maintain_original_method_order) };
+ can_maintain_original_method_order as u64
+ });
+ __bindgen_bitfield_unit.set(16usize, 1u8, {
+ let can_generate_single_step_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_single_step_events) };
+ can_generate_single_step_events as u64
+ });
+ __bindgen_bitfield_unit.set(17usize, 1u8, {
+ let can_generate_exception_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_exception_events) };
+ can_generate_exception_events as u64
+ });
+ __bindgen_bitfield_unit.set(18usize, 1u8, {
+ let can_generate_frame_pop_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_frame_pop_events) };
+ can_generate_frame_pop_events as u64
+ });
+ __bindgen_bitfield_unit.set(19usize, 1u8, {
+ let can_generate_breakpoint_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_breakpoint_events) };
+ can_generate_breakpoint_events as u64
+ });
+ __bindgen_bitfield_unit.set(20usize, 1u8, {
+ let can_suspend: u32 = unsafe { ::std::mem::transmute(can_suspend) };
+ can_suspend as u64
+ });
+ __bindgen_bitfield_unit.set(21usize, 1u8, {
+ let can_redefine_any_class: u32 =
+ unsafe { ::std::mem::transmute(can_redefine_any_class) };
+ can_redefine_any_class as u64
+ });
+ __bindgen_bitfield_unit.set(22usize, 1u8, {
+ let can_get_current_thread_cpu_time: u32 =
+ unsafe { ::std::mem::transmute(can_get_current_thread_cpu_time) };
+ can_get_current_thread_cpu_time as u64
+ });
+ __bindgen_bitfield_unit.set(23usize, 1u8, {
+ let can_get_thread_cpu_time: u32 =
+ unsafe { ::std::mem::transmute(can_get_thread_cpu_time) };
+ can_get_thread_cpu_time as u64
+ });
+ __bindgen_bitfield_unit.set(24usize, 1u8, {
+ let can_generate_method_entry_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_method_entry_events) };
+ can_generate_method_entry_events as u64
+ });
+ __bindgen_bitfield_unit.set(25usize, 1u8, {
+ let can_generate_method_exit_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_method_exit_events) };
+ can_generate_method_exit_events as u64
+ });
+ __bindgen_bitfield_unit.set(26usize, 1u8, {
+ let can_generate_all_class_hook_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_all_class_hook_events) };
+ can_generate_all_class_hook_events as u64
+ });
+ __bindgen_bitfield_unit.set(27usize, 1u8, {
+ let can_generate_compiled_method_load_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_compiled_method_load_events) };
+ can_generate_compiled_method_load_events as u64
+ });
+ __bindgen_bitfield_unit.set(28usize, 1u8, {
+ let can_generate_monitor_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_monitor_events) };
+ can_generate_monitor_events as u64
+ });
+ __bindgen_bitfield_unit.set(29usize, 1u8, {
+ let can_generate_vm_object_alloc_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_vm_object_alloc_events) };
+ can_generate_vm_object_alloc_events as u64
+ });
+ __bindgen_bitfield_unit.set(30usize, 1u8, {
+ let can_generate_native_method_bind_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_native_method_bind_events) };
+ can_generate_native_method_bind_events as u64
+ });
+ __bindgen_bitfield_unit.set(31usize, 1u8, {
+ let can_generate_garbage_collection_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_garbage_collection_events) };
+ can_generate_garbage_collection_events as u64
+ });
+ __bindgen_bitfield_unit.set(32usize, 1u8, {
+ let can_generate_object_free_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_object_free_events) };
+ can_generate_object_free_events as u64
+ });
+ __bindgen_bitfield_unit.set(33usize, 1u8, {
+ let can_force_early_return: u32 =
+ unsafe { ::std::mem::transmute(can_force_early_return) };
+ can_force_early_return as u64
+ });
+ __bindgen_bitfield_unit.set(34usize, 1u8, {
+ let can_get_owned_monitor_stack_depth_info: u32 =
+ unsafe { ::std::mem::transmute(can_get_owned_monitor_stack_depth_info) };
+ can_get_owned_monitor_stack_depth_info as u64
+ });
+ __bindgen_bitfield_unit.set(35usize, 1u8, {
+ let can_get_constant_pool: u32 =
+ unsafe { ::std::mem::transmute(can_get_constant_pool) };
+ can_get_constant_pool as u64
+ });
+ __bindgen_bitfield_unit.set(36usize, 1u8, {
+ let can_set_native_method_prefix: u32 =
+ unsafe { ::std::mem::transmute(can_set_native_method_prefix) };
+ can_set_native_method_prefix as u64
+ });
+ __bindgen_bitfield_unit.set(37usize, 1u8, {
+ let can_retransform_classes: u32 =
+ unsafe { ::std::mem::transmute(can_retransform_classes) };
+ can_retransform_classes as u64
+ });
+ __bindgen_bitfield_unit.set(38usize, 1u8, {
+ let can_retransform_any_class: u32 =
+ unsafe { ::std::mem::transmute(can_retransform_any_class) };
+ can_retransform_any_class as u64
+ });
+ __bindgen_bitfield_unit.set(39usize, 1u8, {
+ let can_generate_resource_exhaustion_heap_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_resource_exhaustion_heap_events) };
+ can_generate_resource_exhaustion_heap_events as u64
+ });
+ __bindgen_bitfield_unit.set(40usize, 1u8, {
+ let can_generate_resource_exhaustion_threads_events: u32 =
+ unsafe { ::std::mem::transmute(can_generate_resource_exhaustion_threads_events) };
+ can_generate_resource_exhaustion_threads_events as u64
+ });
+ __bindgen_bitfield_unit
+ }
+}
diff --git a/tests/headers/issue-816.h b/tests/headers/issue-816.h
new file mode 100644
index 00000000..cacb0260
--- /dev/null
+++ b/tests/headers/issue-816.h
@@ -0,0 +1,49 @@
+typedef struct {
+ unsigned int can_tag_objects : 1;
+ unsigned int can_generate_field_modification_events : 1;
+ unsigned int can_generate_field_access_events : 1;
+ unsigned int can_get_bytecodes : 1;
+ unsigned int can_get_synthetic_attribute : 1;
+ unsigned int can_get_owned_monitor_info : 1;
+ unsigned int can_get_current_contended_monitor : 1;
+ unsigned int can_get_monitor_info : 1;
+ unsigned int can_pop_frame : 1;
+ unsigned int can_redefine_classes : 1;
+ unsigned int can_signal_thread : 1;
+ unsigned int can_get_source_file_name : 1;
+ unsigned int can_get_line_numbers : 1;
+ unsigned int can_get_source_debug_extension : 1;
+ unsigned int can_access_local_variables : 1;
+ unsigned int can_maintain_original_method_order : 1;
+ unsigned int can_generate_single_step_events : 1;
+ unsigned int can_generate_exception_events : 1;
+ unsigned int can_generate_frame_pop_events : 1;
+ unsigned int can_generate_breakpoint_events : 1;
+ unsigned int can_suspend : 1;
+ unsigned int can_redefine_any_class : 1;
+ unsigned int can_get_current_thread_cpu_time : 1;
+ unsigned int can_get_thread_cpu_time : 1;
+ unsigned int can_generate_method_entry_events : 1;
+ unsigned int can_generate_method_exit_events : 1;
+ unsigned int can_generate_all_class_hook_events : 1;
+ unsigned int can_generate_compiled_method_load_events : 1;
+ unsigned int can_generate_monitor_events : 1;
+ unsigned int can_generate_vm_object_alloc_events : 1;
+ unsigned int can_generate_native_method_bind_events : 1;
+ unsigned int can_generate_garbage_collection_events : 1;
+ unsigned int can_generate_object_free_events : 1;
+ unsigned int can_force_early_return : 1;
+ unsigned int can_get_owned_monitor_stack_depth_info : 1;
+ unsigned int can_get_constant_pool : 1;
+ unsigned int can_set_native_method_prefix : 1;
+ unsigned int can_retransform_classes : 1;
+ unsigned int can_retransform_any_class : 1;
+ unsigned int can_generate_resource_exhaustion_heap_events : 1;
+ unsigned int can_generate_resource_exhaustion_threads_events : 1;
+ unsigned int : 7;
+ unsigned int : 16;
+ unsigned int : 16;
+ unsigned int : 16;
+ unsigned int : 16;
+ unsigned int : 16;
+} jvmtiCapabilities;
diff --git a/tests/quickchecking/Cargo.toml b/tests/quickchecking/Cargo.toml
index 2f5b3b71..eb5cdfcf 100644
--- a/tests/quickchecking/Cargo.toml
+++ b/tests/quickchecking/Cargo.toml
@@ -2,9 +2,19 @@
name = "quickchecking"
description = "Bindgen property tests with quickcheck. Generate random valid C code and pass it to the csmith/predicate.py script"
version = "0.1.0"
-authors = ["Shea Newton <snewton@polysync.io>"]
+authors = ["Shea Newton <sheanewt@gmail.com>"]
+
+[lib]
+name = "quickchecking"
+path = "src/lib.rs"
+
+[[bin]]
+name = "quickchecking"
+path = "src/bin.rs"
[dependencies]
+clap = "2.28"
+lazy_static = "1.0"
quickcheck = "0.4"
-tempdir = "0.3"
rand = "0.3"
+tempdir = "0.3"
diff --git a/tests/quickchecking/src/bin.rs b/tests/quickchecking/src/bin.rs
new file mode 100644
index 00000000..9cf313cd
--- /dev/null
+++ b/tests/quickchecking/src/bin.rs
@@ -0,0 +1,110 @@
+//! An application to run property tests for `bindgen` with _fuzzed_ C headers
+//! using `quickcheck`
+//!
+//! ## Usage
+//!
+//! Print help
+//! ```bash
+//! $ cargo run --bin=quickchecking -- -h
+//! ```
+//!
+//! Run with default values
+//! ```bash
+//! $ cargo run --bin=quickchecking
+//! ```
+//!
+#![deny(missing_docs)]
+extern crate clap;
+extern crate quickchecking;
+
+use clap::{App, Arg};
+use std::path::Path;
+
+// Validate CLI argument input for generation range.
+fn validate_generate_range(v: String) -> Result<(), String> {
+ match v.parse::<usize>() {
+ Ok(_) => Ok(()),
+ Err(_) => Err(String::from(
+ "Generate range could not be converted to a usize.",
+ )),
+ }
+}
+
+// Validate CLI argument input for tests count.
+fn validate_tests_count(v: String) -> Result<(), String> {
+ match v.parse::<usize>() {
+ Ok(_) => Ok(()),
+ Err(_) => Err(String::from(
+ "Tests count could not be converted to a usize.",
+ )),
+ }
+}
+
+// Validate CLI argument input for fuzzed headers output path.
+fn validate_path(v: String) -> Result<(), String> {
+ match Path::new(&v).is_dir() {
+ true => Ok(()),
+ false => Err(String::from("Provided directory path does not exist.")),
+ }
+}
+
+fn main() {
+ let matches = App::new("quickchecking")
+ .version("0.2.0")
+ .about(
+ "Bindgen property tests with quickcheck. \
+ Generate random valid C code and pass it to the \
+ csmith/predicate.py script",
+ )
+ .arg(
+ Arg::with_name("path")
+ .short("p")
+ .long("path")
+ .value_name("PATH")
+ .help(
+ "Optional. Preserve generated headers for inspection, \
+ provide directory path for header output. [default: None] ",
+ )
+ .takes_value(true)
+ .validator(validate_path),
+ )
+ .arg(
+ Arg::with_name("range")
+ .short("r")
+ .long("range")
+ .value_name("RANGE")
+ .help(
+ "Sets the range quickcheck uses during generation. \
+ Corresponds to things like arbitrary usize and \
+ arbitrary vector length. This number doesn't have \
+ to grow much for that execution time to increase \
+ significantly.",
+ )
+ .takes_value(true)
+ .default_value("32")
+ .validator(validate_generate_range),
+ )
+ .arg(
+ Arg::with_name("count")
+ .short("c")
+ .long("count")
+ .value_name("COUNT")
+ .help(
+ "Count / number of tests to run. Running a fuzzed \
+ header through the predicate.py script can take a \
+ long time, especially if the generation range is \
+ large. Increase this number if you're willing to \
+ wait a while.",
+ )
+ .takes_value(true)
+ .default_value("2")
+ .validator(validate_tests_count),
+ )
+ .get_matches();
+
+ let output_path: Option<&str> = matches.value_of("path");
+ let generate_range: usize = matches.value_of("range").unwrap().parse::<usize>().unwrap();
+ let tests: usize = matches.value_of("count").unwrap().parse::<usize>().unwrap();
+
+ quickchecking::test_bindgen(generate_range, tests, output_path)
+}
diff --git a/tests/quickchecking/src/lib.rs b/tests/quickchecking/src/lib.rs
index 3bea8a8e..d8633dfb 100644
--- a/tests/quickchecking/src/lib.rs
+++ b/tests/quickchecking/src/lib.rs
@@ -20,9 +20,107 @@
//! ```
//!
#![deny(missing_docs)]
+#[macro_use]
+extern crate lazy_static;
extern crate quickcheck;
extern crate rand;
extern crate tempdir;
+use std::sync::Mutex;
+use quickcheck::{QuickCheck, StdGen, TestResult};
+use std::fs::File;
+use std::io::Write;
+use tempdir::TempDir;
+use std::process::{Command, Output};
+use std::path::PathBuf;
+use std::error::Error;
+use rand::thread_rng;
+
/// Contains definitions of and impls for types used to fuzz C declarations.
pub mod fuzzers;
+
+// Global singleton, manages context across tests. For now that context is
+// only the output_path for inspecting fuzzed headers (if specified).
+struct Context {
+ output_path: Option<String>,
+}
+
+// Initialize global context.
+lazy_static! {
+ static ref CONTEXT: Mutex<Context> = Mutex::new(Context { output_path: None });
+}
+
+// Passes fuzzed header to the `csmith-fuzzing/predicate.py` script, returns
+// output of the associated command.
+fn run_predicate_script(header: fuzzers::HeaderC) -> Result<Output, Box<Error>> {
+ let dir = TempDir::new("bindgen_prop")?;
+ let header_path = dir.path().join("prop_test.h");
+
+ let mut header_file = File::create(&header_path)?;
+ header_file.write_all(header.to_string().as_bytes())?;
+ header_file.sync_all()?;
+
+ let header_path_string;
+ match header_path.into_os_string().into_string() {
+ Ok(s) => header_path_string = s,
+ Err(_) => return Err(From::from("error converting path into String")),
+ }
+
+ let mut predicate_script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+ predicate_script_path.push("../../csmith-fuzzing/predicate.py");
+
+ let predicate_script_path_string;
+ match predicate_script_path.into_os_string().into_string() {
+ Ok(s) => predicate_script_path_string = s,
+ Err(_) => return Err(From::from("error converting path into String")),
+ }
+
+ // Copy generated temp files to output_path directory for inspection.
+ // If `None`, output path not specified, don't copy.
+ match CONTEXT.lock().unwrap().output_path {
+ Some(ref path) => {
+ Command::new("cp")
+ .arg("-a")
+ .arg(&dir.path().to_str().unwrap())
+ .arg(&path)
+ .output()?;
+ }
+ None => {}
+ }
+
+ Ok(Command::new(&predicate_script_path_string)
+ .arg(&header_path_string)
+ .output()?)
+}
+
+// Generatable property. Pass generated headers off to run through the
+// `csmith-fuzzing/predicate.py` script. Success is measured by the success
+// status of that command.
+fn bindgen_prop(header: fuzzers::HeaderC) -> TestResult {
+ match run_predicate_script(header) {
+ Ok(o) => return TestResult::from_bool(o.status.success()),
+ Err(e) => {
+ println!("{:?}", e);
+ return TestResult::from_bool(false);
+ }
+ }
+}
+
+/// Instantiate a Quickcheck object and use it to run property tests using
+/// fuzzed C headers generated with types defined in the `fuzzers` module.
+/// Success/Failure is dictated by the result of passing the fuzzed headers
+/// to the `csmith-fuzzing/predicate.py` script.
+pub fn test_bindgen(generate_range: usize, tests: usize, output_path: Option<&str>) {
+ match output_path {
+ Some(path) => {
+ CONTEXT.lock().unwrap().output_path =
+ Some(String::from(PathBuf::from(path).to_str().unwrap()));
+ }
+ None => {} // Path not specified, don't provide output.
+ }
+
+ QuickCheck::new()
+ .tests(tests)
+ .gen(StdGen::new(thread_rng(), generate_range))
+ .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult)
+}
diff --git a/tests/quickchecking/tests/fuzzed-c-headers.rs b/tests/quickchecking/tests/fuzzed-c-headers.rs
index f550cf0c..6b58d24b 100644
--- a/tests/quickchecking/tests/fuzzed-c-headers.rs
+++ b/tests/quickchecking/tests/fuzzed-c-headers.rs
@@ -1,78 +1,95 @@
+
extern crate quickcheck;
extern crate quickchecking;
extern crate rand;
-extern crate tempdir;
-
-use quickchecking::fuzzers;
-use quickcheck::{QuickCheck, StdGen, TestResult};
-use std::fs::File;
-use std::io::Write;
-use tempdir::TempDir;
-use std::process::{Command, Output};
-use std::path::PathBuf;
-use std::error::Error;
+
+use quickchecking::fuzzers::{ArrayDimensionC, BaseTypeC, BasicTypeDeclarationC, DeclarationC,
+ DeclarationListC, FunctionPointerDeclarationC, FunctionPrototypeC,
+ HeaderC, ParameterC, ParameterListC, PointerLevelC,
+ StructDeclarationC, TypeQualifierC, UnionDeclarationC};
+use quickcheck::{Arbitrary, StdGen};
use rand::thread_rng;
-fn run_predicate_script(header: fuzzers::HeaderC, header_name: &str) -> Result<Output, Box<Error>> {
- let dir = TempDir::new("bindgen_prop")?;
- let header_path = dir.path().join(header_name);
-
- let mut header_file = File::create(&header_path)?;
- header_file.write_all(header.to_string().as_bytes())?;
- header_file.sync_all()?;
-
- let header_path_string;
- match header_path.into_os_string().into_string() {
- Ok(s) => header_path_string = s,
- Err(_) => return Err(From::from("error converting path into String")),
- }
-
- let mut predicate_script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
- predicate_script_path.push("../../csmith-fuzzing/predicate.py");
-
- let predicate_script_path_string;
- match predicate_script_path.into_os_string().into_string() {
- Ok(s) => predicate_script_path_string = s,
- Err(_) => return Err(From::from("error converting path into String")),
- }
-
- // Copy generated temp files to test directory for inspection.
- // Preserved for anyone interested in validating the behavior.
-
- let mut debug_output_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
- debug_output_path.push("tests");
- Command::new("cp")
- .arg("-a")
- .arg(&dir.path().to_str().unwrap())
- .arg(&debug_output_path.to_str().unwrap())
- .output()?;
-
- Ok(Command::new(&predicate_script_path_string)
- .arg(&header_path_string)
- .output()?)
+#[test]
+fn test_declaraion_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: DeclarationC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_declaraion_list_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: DeclarationListC = Arbitrary::arbitrary(gen);
}
-fn bindgen_prop(header: fuzzers::HeaderC) -> TestResult {
- match run_predicate_script(header, "prop_test.h") {
- Ok(o) => return TestResult::from_bool(o.status.success()),
- Err(e) => {
- println!("{:?}", e);
- return TestResult::from_bool(false);
- }
- }
+#[test]
+fn test_base_type_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: BaseTypeC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_type_qualifier_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: TypeQualifierC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_pointer_level_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: PointerLevelC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_array_dimension_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: ArrayDimensionC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_basic_type_declaration_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: BasicTypeDeclarationC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_struct_declaration_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: StructDeclarationC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_union_declaration_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: UnionDeclarationC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_function_pointer_declaration_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: FunctionPointerDeclarationC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_function_prototype_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: FunctionPrototypeC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_parameter_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: ParameterC = Arbitrary::arbitrary(gen);
+}
+
+#[test]
+fn test_parameter_list_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: ParameterListC = Arbitrary::arbitrary(gen);
}
#[test]
-fn test_bindgen() {
- // Enough to generate any value in the PrimitiveTypeC `base_type` list.
- let generate_range: usize = 32;
- QuickCheck::new()
- // Generating is relatively quick (generate_range 150 takes ~5 seconds)
- // but running predicate.py takes ~30 seconds per source file / test
- // when the generation range is just 32. It can take a lot longer with a
- // higher generate_range. Up the number of tests or generate_range if
- // you're willing to wait awhile.
- .tests(2)
- .gen(StdGen::new(thread_rng(), generate_range))
- .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult)
+fn test_header_c_does_not_panic() {
+ let ref mut gen = StdGen::new(thread_rng(), 50);
+ let _: HeaderC = Arbitrary::arbitrary(gen);
}