From 0cd358742dfcf3fa6b0d8a318cfb5cc748dc905d Mon Sep 17 00:00:00 2001 From: Alexey Tarasov Date: Sat, 12 Aug 2017 18:42:44 +1000 Subject: [PATCH 1/3] Fixes issue 39827: ICE in volatile_store intrinsic - adds handling of zero-sized types for volatile_store. - adds type size checks and warnigns for other volatile intrinsics. - adds a test to check warnings emitting. Cause of the issue While preparing for trans_intrinsic_call() invoke arguments are processed with trans_argument() method which excludes zero-sized types from argument list (to be more correct - all arguments for which ArgKind is Ignore are filtered out). As result volatile_store() intrinsic gets one argument instead of expected address and value. How it is fixed Modification of the trans_argument() method may cause side effects, therefore change was implemented in volatile_store() intrinsic building code itself. Now it checks function signature and if it was specialised with zero-sized type, then emits C_nil() instead of accessing non-existing second argument. Additionally warnings are added for all volatile operations which are specialised with zero-sized arguments. In fact, those operations are omitted in LLVM backend if no memory affected at all, e.g. number of elements is zero or type is zero-sized. This was not explicitly documented before and could lead to potential issues if developer expects volatile behaviour, but type has degraded to zero-sized. --- src/librustc_trans/intrinsic.rs | 52 +++++++++++++++++++++-- src/test/ui/issue-39827.rs | 37 +++++++++++++++++ src/test/ui/issue-39827.stderr | 73 +++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/issue-39827.rs create mode 100644 src/test/ui/issue-39827.stderr diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 9956c28e64121..5ebd9bed5c8c8 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -83,6 +83,38 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option { Some(ccx.get_intrinsic(&llvm_name)) } +fn warn_if_size_is_weird<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, + tp_ty: Ty<'tcx>, + count: ValueRef, + span: Span, + name: &str) { + let ccx = bcx.ccx; + let lltp_ty = type_of::type_of(ccx, tp_ty); + let ty_size = machine::llsize_of(ccx, lltp_ty); + let total = const_to_uint( bcx.mul(ty_size, count) ); + + if total > 0 { + return; + } + + let text = format!("suspicious monomorphization of `{}` intrinsic", name); + let note = match name + { + "volatile_load" | "volatile_store" => + format!("'{}' was specialized with zero-sized type '{}'", + name, tp_ty), + _ => format!("'{}' was specialized with type '{}', number of \ + elements is {}", + name, tp_ty, + const_to_uint(count)) + }; + + let sess = bcx.sess(); + sess.struct_span_warn(span, &text) + .note(¬e) + .emit(); +} + /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_trans/trans/context.rs @@ -217,17 +249,24 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, } "volatile_copy_nonoverlapping_memory" => { - copy_intrinsic(bcx, false, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) + let tp_ty = substs.type_at(0); + warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); + copy_intrinsic(bcx, false, true, tp_ty, llargs[0], llargs[1], llargs[2]) } "volatile_copy_memory" => { - copy_intrinsic(bcx, true, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) + let tp_ty = substs.type_at(0); + warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); + copy_intrinsic(bcx, true, true, tp_ty, llargs[0], llargs[1], llargs[2]) } "volatile_set_memory" => { - memset_intrinsic(bcx, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) + let tp_ty = substs.type_at(0); + warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); + memset_intrinsic(bcx, true, tp_ty, llargs[0], llargs[1], llargs[2]) } "volatile_load" => { let tp_ty = substs.type_at(0); let mut ptr = llargs[0]; + warn_if_size_is_weird(bcx, tp_ty, C_uint(ccx,1usize), span, name); if let Some(ty) = fn_ty.ret.cast { ptr = bcx.pointercast(ptr, ty.ptr_to()); } @@ -239,6 +278,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, }, "volatile_store" => { let tp_ty = substs.type_at(0); + warn_if_size_is_weird(bcx, tp_ty, C_uint(ccx,1usize), span, name); if type_is_fat_ptr(bcx.ccx, tp_ty) { bcx.volatile_store(llargs[1], get_dataptr(bcx, llargs[0])); bcx.volatile_store(llargs[2], get_meta(bcx, llargs[0])); @@ -246,7 +286,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let val = if fn_ty.args[1].is_indirect() { bcx.load(llargs[1], None) } else { - from_immediate(bcx, llargs[1]) + if !type_is_zero_size(ccx, tp_ty) { + from_immediate(bcx, llargs[1]) + } else { + C_nil(ccx) + } }; let ptr = bcx.pointercast(llargs[0], val_ty(val).ptr_to()); let store = bcx.volatile_store(val, ptr); diff --git a/src/test/ui/issue-39827.rs b/src/test/ui/issue-39827.rs new file mode 100644 index 0000000000000..86a3f67b40a87 --- /dev/null +++ b/src/test/ui/issue-39827.rs @@ -0,0 +1,37 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(core_intrinsics)] + +use std::intrinsics::{ volatile_copy_memory, volatile_store, volatile_load, + volatile_copy_nonoverlapping_memory, + volatile_set_memory }; + +fn main () { + let mut dst_pair = (1, 2); + let src_pair = (3, 4); + let mut dst_empty = (); + let src_empty = (); + + const COUNT_0: usize = 0; + const COUNT_100: usize = 100; + + unsafe { + volatile_copy_memory(&mut dst_pair, &dst_pair, COUNT_0); + volatile_copy_nonoverlapping_memory(&mut dst_pair, &src_pair, 0); + volatile_copy_memory(&mut dst_empty, &dst_empty, 100); + volatile_copy_nonoverlapping_memory(&mut dst_empty, &src_empty, + COUNT_100); + volatile_set_memory(&mut dst_empty, 0, COUNT_100); + volatile_set_memory(&mut dst_pair, 0, COUNT_0); + volatile_store(&mut dst_empty, ()); + volatile_store(&mut dst_empty, src_empty); + volatile_load(&src_empty); + } +} diff --git a/src/test/ui/issue-39827.stderr b/src/test/ui/issue-39827.stderr new file mode 100644 index 0000000000000..228309872f939 --- /dev/null +++ b/src/test/ui/issue-39827.stderr @@ -0,0 +1,73 @@ +warning: suspicious monomorphization of `volatile_copy_memory` intrinsic + --> $DIR/issue-39827.rs:26:9 + | +26 | volatile_copy_memory(&mut dst_pair, &dst_pair, COUNT_0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_copy_memory' was specialized with type '(i32, i32)', number of elements is 0 + +warning: suspicious monomorphization of `volatile_copy_nonoverlapping_memory` intrinsic + --> $DIR/issue-39827.rs:27:9 + | +27 | volatile_copy_nonoverlapping_memory(&mut dst_pair, &src_pair, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_copy_nonoverlapping_memory' was specialized with type '(i32, i32)', number of elements is 0 + +warning: suspicious monomorphization of `volatile_copy_memory` intrinsic + --> $DIR/issue-39827.rs:28:9 + | +28 | volatile_copy_memory(&mut dst_empty, &dst_empty, 100); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_copy_memory' was specialized with type '()', number of elements is 100 + +warning: suspicious monomorphization of `volatile_copy_nonoverlapping_memory` intrinsic + --> $DIR/issue-39827.rs:29:9 + | +29 | / volatile_copy_nonoverlapping_memory(&mut dst_empty, &src_empty, +30 | | COUNT_100); + | |______________________________________________________^ + | + = note: 'volatile_copy_nonoverlapping_memory' was specialized with type '()', number of elements is 100 + +warning: suspicious monomorphization of `volatile_set_memory` intrinsic + --> $DIR/issue-39827.rs:31:9 + | +31 | volatile_set_memory(&mut dst_empty, 0, COUNT_100); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_set_memory' was specialized with type '()', number of elements is 100 + +warning: suspicious monomorphization of `volatile_set_memory` intrinsic + --> $DIR/issue-39827.rs:32:9 + | +32 | volatile_set_memory(&mut dst_pair, 0, COUNT_0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_set_memory' was specialized with type '(i32, i32)', number of elements is 0 + +warning: suspicious monomorphization of `volatile_store` intrinsic + --> $DIR/issue-39827.rs:33:9 + | +33 | volatile_store(&mut dst_empty, ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_store' was specialized with zero-sized type '()' + +warning: suspicious monomorphization of `volatile_store` intrinsic + --> $DIR/issue-39827.rs:34:9 + | +34 | volatile_store(&mut dst_empty, src_empty); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_store' was specialized with zero-sized type '()' + +warning: suspicious monomorphization of `volatile_load` intrinsic + --> $DIR/issue-39827.rs:35:9 + | +35 | volatile_load(&src_empty); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: 'volatile_load' was specialized with zero-sized type '()' + From 6a607faba43a818e2a9d63f87316256a963277bb Mon Sep 17 00:00:00 2001 From: Alexey Tarasov Date: Sat, 12 Aug 2017 18:43:59 +1000 Subject: [PATCH 2/3] Follow up commit for the issue 39827 - updates documentation on volatile memory intrinsics, now the case of zero-sized types is mentioned explicitly. Volatile memory operations which doesn't affect memory at all are omitted in LLVM backend, e.g. if number of elements is zero or type used in generic specialisation is zero-sized, then LLVM intrinsic or related code is not generated. This was not explicitly documented before in Rust documentation and potentially could cause issues. --- src/libcore/intrinsics.rs | 9 ++++++--- src/libcore/ptr.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index fdca8d00d7a75..ad776c8605ac8 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1044,20 +1044,23 @@ extern "rust-intrinsic" { /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero. pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero.. pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count` * `size_of::()` and an alignment of /// `min_align_of::()`. /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero. pub fn volatile_set_memory(dst: *mut T, val: u8, count: usize); /// Perform a volatile load from the `src` pointer. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 60cf1a2053068..b37e3a5236d1c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -384,6 +384,12 @@ pub unsafe fn write_unaligned(dst: *mut T, src: T) { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// +/// Compiler shouldn't change relative order or number of volatile memory +/// operations, however this implies that memory operation actually takes place. +/// If a zero-sized type is used in a specialisation of `read_volatile`, value +/// is known at any time and can not be modified outside of program control. +/// In this case such operation may be omitted by compiler backend. +/// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// /// # Safety @@ -427,6 +433,12 @@ pub unsafe fn read_volatile(src: *const T) -> T { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// +/// Compiler shouldn't change relative order or number of volatile memory +/// operations, however this implies that memory operation actually takes place. +/// If a zero-sized type is used in a specialisation of `write_volatile`, value +/// is known at any time and can not be modified outside of program control. +/// In this case such operation may be omitted by compiler backend. +/// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// /// # Safety From faf6b84304dbc96f7bf142973f394f820e390a4c Mon Sep 17 00:00:00 2001 From: Alexey Tarasov Date: Sun, 13 Aug 2017 19:28:04 +1000 Subject: [PATCH 3/3] Addresses comments in PR #43836 - removes warnings introduced in changeset 0cd3587 - makes documentation more neat and grammatically correct --- src/libcore/ptr.rs | 18 +++--- src/librustc_trans/intrinsic.rs | 46 +-------------- src/test/{ui => run-pass}/issue-39827.rs | 5 ++ src/test/ui/issue-39827.stderr | 73 ------------------------ 4 files changed, 16 insertions(+), 126 deletions(-) rename src/test/{ui => run-pass}/issue-39827.rs (89%) delete mode 100644 src/test/ui/issue-39827.stderr diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b37e3a5236d1c..e35777d222c06 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -384,11 +384,10 @@ pub unsafe fn write_unaligned(dst: *mut T, src: T) { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// -/// Compiler shouldn't change relative order or number of volatile memory -/// operations, however this implies that memory operation actually takes place. -/// If a zero-sized type is used in a specialisation of `read_volatile`, value -/// is known at any time and can not be modified outside of program control. -/// In this case such operation may be omitted by compiler backend. +/// The compiler shouldn't change the relative order or number of volatile +/// memory operations. However, volatile memory operations on zero-sized types +/// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops +/// and may be ignored. /// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// @@ -433,11 +432,10 @@ pub unsafe fn read_volatile(src: *const T) -> T { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// -/// Compiler shouldn't change relative order or number of volatile memory -/// operations, however this implies that memory operation actually takes place. -/// If a zero-sized type is used in a specialisation of `write_volatile`, value -/// is known at any time and can not be modified outside of program control. -/// In this case such operation may be omitted by compiler backend. +/// The compiler shouldn't change the relative order or number of volatile +/// memory operations. However, volatile memory operations on zero-sized types +/// (e.g. if a zero-sized type is passed to `write_volatile`) are no-ops +/// and may be ignored. /// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 5ebd9bed5c8c8..033ef988571dd 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -83,38 +83,6 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option { Some(ccx.get_intrinsic(&llvm_name)) } -fn warn_if_size_is_weird<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - tp_ty: Ty<'tcx>, - count: ValueRef, - span: Span, - name: &str) { - let ccx = bcx.ccx; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let ty_size = machine::llsize_of(ccx, lltp_ty); - let total = const_to_uint( bcx.mul(ty_size, count) ); - - if total > 0 { - return; - } - - let text = format!("suspicious monomorphization of `{}` intrinsic", name); - let note = match name - { - "volatile_load" | "volatile_store" => - format!("'{}' was specialized with zero-sized type '{}'", - name, tp_ty), - _ => format!("'{}' was specialized with type '{}', number of \ - elements is {}", - name, tp_ty, - const_to_uint(count)) - }; - - let sess = bcx.sess(); - sess.struct_span_warn(span, &text) - .note(¬e) - .emit(); -} - /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_trans/trans/context.rs @@ -249,24 +217,17 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, } "volatile_copy_nonoverlapping_memory" => { - let tp_ty = substs.type_at(0); - warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); - copy_intrinsic(bcx, false, true, tp_ty, llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, false, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) } "volatile_copy_memory" => { - let tp_ty = substs.type_at(0); - warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); - copy_intrinsic(bcx, true, true, tp_ty, llargs[0], llargs[1], llargs[2]) + copy_intrinsic(bcx, true, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) } "volatile_set_memory" => { - let tp_ty = substs.type_at(0); - warn_if_size_is_weird(bcx, tp_ty, llargs[2], span, name); - memset_intrinsic(bcx, true, tp_ty, llargs[0], llargs[1], llargs[2]) + memset_intrinsic(bcx, true, substs.type_at(0), llargs[0], llargs[1], llargs[2]) } "volatile_load" => { let tp_ty = substs.type_at(0); let mut ptr = llargs[0]; - warn_if_size_is_weird(bcx, tp_ty, C_uint(ccx,1usize), span, name); if let Some(ty) = fn_ty.ret.cast { ptr = bcx.pointercast(ptr, ty.ptr_to()); } @@ -278,7 +239,6 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, }, "volatile_store" => { let tp_ty = substs.type_at(0); - warn_if_size_is_weird(bcx, tp_ty, C_uint(ccx,1usize), span, name); if type_is_fat_ptr(bcx.ccx, tp_ty) { bcx.volatile_store(llargs[1], get_dataptr(bcx, llargs[0])); bcx.volatile_store(llargs[2], get_meta(bcx, llargs[0])); diff --git a/src/test/ui/issue-39827.rs b/src/test/run-pass/issue-39827.rs similarity index 89% rename from src/test/ui/issue-39827.rs rename to src/test/run-pass/issue-39827.rs index 86a3f67b40a87..b753cf5844fa9 100644 --- a/src/test/ui/issue-39827.rs +++ b/src/test/run-pass/issue-39827.rs @@ -13,6 +13,11 @@ use std::intrinsics::{ volatile_copy_memory, volatile_store, volatile_load, volatile_copy_nonoverlapping_memory, volatile_set_memory }; +// +// This test ensures that volatile intrinsics can be specialised with +// zero-sized types and, in case of copy/set functions, can accept +// number of elements equal to zero. +// fn main () { let mut dst_pair = (1, 2); let src_pair = (3, 4); diff --git a/src/test/ui/issue-39827.stderr b/src/test/ui/issue-39827.stderr deleted file mode 100644 index 228309872f939..0000000000000 --- a/src/test/ui/issue-39827.stderr +++ /dev/null @@ -1,73 +0,0 @@ -warning: suspicious monomorphization of `volatile_copy_memory` intrinsic - --> $DIR/issue-39827.rs:26:9 - | -26 | volatile_copy_memory(&mut dst_pair, &dst_pair, COUNT_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_copy_memory' was specialized with type '(i32, i32)', number of elements is 0 - -warning: suspicious monomorphization of `volatile_copy_nonoverlapping_memory` intrinsic - --> $DIR/issue-39827.rs:27:9 - | -27 | volatile_copy_nonoverlapping_memory(&mut dst_pair, &src_pair, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_copy_nonoverlapping_memory' was specialized with type '(i32, i32)', number of elements is 0 - -warning: suspicious monomorphization of `volatile_copy_memory` intrinsic - --> $DIR/issue-39827.rs:28:9 - | -28 | volatile_copy_memory(&mut dst_empty, &dst_empty, 100); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_copy_memory' was specialized with type '()', number of elements is 100 - -warning: suspicious monomorphization of `volatile_copy_nonoverlapping_memory` intrinsic - --> $DIR/issue-39827.rs:29:9 - | -29 | / volatile_copy_nonoverlapping_memory(&mut dst_empty, &src_empty, -30 | | COUNT_100); - | |______________________________________________________^ - | - = note: 'volatile_copy_nonoverlapping_memory' was specialized with type '()', number of elements is 100 - -warning: suspicious monomorphization of `volatile_set_memory` intrinsic - --> $DIR/issue-39827.rs:31:9 - | -31 | volatile_set_memory(&mut dst_empty, 0, COUNT_100); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_set_memory' was specialized with type '()', number of elements is 100 - -warning: suspicious monomorphization of `volatile_set_memory` intrinsic - --> $DIR/issue-39827.rs:32:9 - | -32 | volatile_set_memory(&mut dst_pair, 0, COUNT_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_set_memory' was specialized with type '(i32, i32)', number of elements is 0 - -warning: suspicious monomorphization of `volatile_store` intrinsic - --> $DIR/issue-39827.rs:33:9 - | -33 | volatile_store(&mut dst_empty, ()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_store' was specialized with zero-sized type '()' - -warning: suspicious monomorphization of `volatile_store` intrinsic - --> $DIR/issue-39827.rs:34:9 - | -34 | volatile_store(&mut dst_empty, src_empty); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_store' was specialized with zero-sized type '()' - -warning: suspicious monomorphization of `volatile_load` intrinsic - --> $DIR/issue-39827.rs:35:9 - | -35 | volatile_load(&src_empty); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: 'volatile_load' was specialized with zero-sized type '()' -