@@ -10,8 +10,8 @@ use rustc_middle::{bug, mir, span_bug};
1010use rustc_target:: abi:: call:: { FnAbi , PassMode } ;
1111use tracing:: { debug, instrument} ;
1212
13- use crate :: base;
1413use crate :: traits:: * ;
14+ use crate :: { base, errors} ;
1515
1616mod analyze;
1717mod block;
@@ -29,6 +29,8 @@ use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo};
2929use self :: operand:: { OperandRef , OperandValue } ;
3030use self :: place:: PlaceRef ;
3131
32+ const MIN_DANGEROUS_SIZE : u64 = 1024 * 1024 * 1024 * 1 ; // 1 GB
33+
3234// Used for tracking the state of generated basic blocks.
3335enum CachedLlbb < T > {
3436 /// Nothing created yet.
@@ -234,6 +236,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
234236 let layout = start_bx. layout_of ( fx. monomorphize ( decl. ty ) ) ;
235237 assert ! ( !layout. ty. has_erasable_regions( ) ) ;
236238
239+ if layout. size . bytes ( ) >= MIN_DANGEROUS_SIZE {
240+ let ( size_quantity, size_unit) = human_readable_bytes ( layout. size . bytes ( ) ) ;
241+ cx. tcx ( ) . dcx ( ) . emit_warn ( errors:: DangerousStackAllocation {
242+ span : decl. source_info . span ,
243+ output : format ! ( "{:.2} {}" , size_quantity, size_unit) ,
244+ } ) ;
245+ }
246+
237247 if local == mir:: RETURN_PLACE {
238248 match fx. fn_abi . ret . mode {
239249 PassMode :: Indirect { .. } => {
@@ -299,6 +309,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
299309 }
300310}
301311
312+ /// Formats a number of bytes into a human readable SI-prefixed size.
313+ /// Returns a tuple of `(quantity, units)`.
314+ pub fn human_readable_bytes ( bytes : u64 ) -> ( u64 , & ' static str ) {
315+ static UNITS : [ & str ; 7 ] = [ "B" , "KiB" , "MiB" , "GiB" , "TiB" , "PiB" , "EiB" ] ;
316+ let i = ( ( bytes. checked_ilog2 ( ) . unwrap_or ( 0 ) / 10 ) as usize ) . min ( UNITS . len ( ) - 1 ) ;
317+ ( bytes >> ( 10 * i) , UNITS [ i] )
318+ }
319+
302320/// Produces, for each argument, a `Value` pointing at the
303321/// argument's value. As arguments are places, these are always
304322/// indirect.
0 commit comments