@@ -30,50 +30,57 @@ use rustc::ty::{self, Ty, TyCtxt};
3030use syntax:: parse:: token;
3131use rustc:: hir;
3232use rustc_const_math:: { ConstInt , ConstUsize } ;
33- use syntax:: attr;
33+ use syntax:: attr:: AttrMetaMethods ;
3434
3535#[ derive( Copy , Clone ) ]
3636pub struct Cx < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
3737 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
3838 infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
3939 constness : hir:: Constness ,
4040
41- /// True if this MIR can get inlined in other crates .
42- inline : bool
41+ /// True if this constant/function needs overflow checks .
42+ check_overflow : bool
4343}
4444
4545impl < ' a , ' gcx , ' tcx > Cx < ' a , ' gcx , ' tcx > {
4646 pub fn new ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
4747 src : MirSource )
4848 -> Cx < ' a , ' gcx , ' tcx > {
49- let ( constness, inline ) = match src {
49+ let constness = match src {
5050 MirSource :: Const ( _) |
51- MirSource :: Static ( ..) => ( hir:: Constness :: Const , false ) ,
51+ MirSource :: Static ( ..) => hir:: Constness :: Const ,
5252 MirSource :: Fn ( id) => {
53- let def_id = infcx. tcx . map . local_def_id ( id) ;
5453 let fn_like = FnLikeNode :: from_node ( infcx. tcx . map . get ( id) ) ;
5554 match fn_like. map ( |f| f. kind ( ) ) {
56- Some ( FnKind :: ItemFn ( _, _, _, c, _, _, attrs) ) => {
57- let scheme = infcx. tcx . lookup_item_type ( def_id) ;
58- let any_types = !scheme. generics . types . is_empty ( ) ;
59- ( c, any_types || attr:: requests_inline ( attrs) )
60- }
61- Some ( FnKind :: Method ( _, m, _, attrs) ) => {
62- let scheme = infcx. tcx . lookup_item_type ( def_id) ;
63- let any_types = !scheme. generics . types . is_empty ( ) ;
64- ( m. constness , any_types || attr:: requests_inline ( attrs) )
65- }
66- _ => ( hir:: Constness :: NotConst , true )
55+ Some ( FnKind :: ItemFn ( _, _, _, c, _, _, _) ) => c,
56+ Some ( FnKind :: Method ( _, m, _, _) ) => m. constness ,
57+ _ => hir:: Constness :: NotConst
6758 }
6859 }
6960 MirSource :: Promoted ( ..) => bug ! ( )
7061 } ;
7162
63+ let attrs = infcx. tcx . map . attrs ( src. item_id ( ) ) ;
64+
65+ // Some functions always have overflow checks enabled,
66+ // however, they may not get codegen'd, depending on
67+ // the settings for the crate they are translated in.
68+ let mut check_overflow = attrs. iter ( ) . any ( |item| {
69+ item. check_name ( "rustc_inherit_overflow_checks" )
70+ } ) ;
71+
72+ // Respect -Z force-overflow-checks=on and -C debug-assertions.
73+ check_overflow |= infcx. tcx . sess . opts . debugging_opts . force_overflow_checks
74+ . unwrap_or ( infcx. tcx . sess . opts . debug_assertions ) ;
75+
76+ // Constants and const fn's always need overflow checks.
77+ check_overflow |= constness == hir:: Constness :: Const ;
78+
7279 Cx {
7380 tcx : infcx. tcx ,
7481 infcx : infcx,
7582 constness : constness,
76- inline : inline
83+ check_overflow : check_overflow
7784 }
7885 }
7986}
@@ -186,8 +193,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
186193 self . tcx
187194 }
188195
189- pub fn may_be_inlined_cross_crate ( & self ) -> bool {
190- self . inline
196+ pub fn check_overflow ( & self ) -> bool {
197+ self . check_overflow
191198 }
192199}
193200
0 commit comments