@@ -3062,68 +3062,59 @@ impl<'tcx> LateLintPass<'tcx> for ReturningPointersToLocalVariables {
3062
3062
impl ReturningPointersToLocalVariables {
3063
3063
/// Evaluates the return expression of a function and emits a lint if it
3064
3064
/// returns a pointer to a local variable.
3065
- fn maybe_lint_return_expr < ' tcx > ( cx : & LateContext < ' tcx > , return_expr : & hir:: Expr < ' tcx > , params : & ' tcx [ hir:: Ty < ' tcx > ] ) {
3066
- // dbg!(return_expr);
3067
- if let hir:: Expr { kind : hir:: ExprKind :: AddrOf ( _, _, addr_expr) , .. }
3068
- | hir:: Expr {
3069
- kind :
3070
- hir:: ExprKind :: Cast ( hir:: Expr { kind : hir:: ExprKind :: AddrOf ( _, _, addr_expr) , .. } , _) ,
3071
- ..
3072
- } = return_expr
3073
- {
3074
- if let hir:: ExprKind :: Path (
3075
- hir:: QPath :: Resolved ( _, hir:: Path { res : hir:: def:: Res :: Local ( _) , .. } ) ,
3076
- ..,
3077
- ) = addr_expr. kind
3078
- {
3079
- cx. emit_span_lint (
3080
- RETURNING_POINTERS_TO_LOCAL_VARIABLES ,
3081
- return_expr. span ,
3082
- BuiltinReturningPointersToLocalVariables ,
3083
- ) ;
3084
- }
3065
+ fn maybe_lint_return_expr < ' tcx > (
3066
+ cx : & LateContext < ' tcx > ,
3067
+ return_expr : & hir:: Expr < ' tcx > ,
3068
+ params : & ' tcx [ hir:: Ty < ' tcx > ] ,
3069
+ ) {
3070
+ // Early exit if we see that this is a pointer to an input parameter.
3071
+ if Self :: expr_is_param ( cx. typeck_results ( ) , return_expr, params) {
3072
+ return ;
3085
3073
}
3086
- if let hir:: Expr {
3087
- kind :
3088
- hir:: ExprKind :: Cast (
3089
- hir:: Expr {
3090
- hir_id,
3091
- kind :
3092
- hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
3093
- _,
3094
- hir:: Path { res : hir:: def:: Res :: Local ( _) , .. } ,
3095
- ) ) ,
3096
- ..
3097
- } ,
3098
- _,
3099
- ) ,
3100
- ..
3101
- } = return_expr
3102
- {
3103
-
3104
- if let hir:: Node :: Pat ( hir:: Pat {
3105
- hir_id : pat_id,
3106
- ..
3107
- } ) = cx. tcx . hir_node ( * hir_id) {
3108
- if !params. iter ( ) . map ( |param| param. hir_id ) . collect :: < Vec < _ > > ( ) . contains ( pat_id) {
3109
- println ! ( "No param ty" ) ;
3110
- cx. emit_span_lint (
3111
- RETURNING_POINTERS_TO_LOCAL_VARIABLES ,
3112
- return_expr. span ,
3113
- BuiltinReturningPointersToLocalVariables ,
3114
- ) ;
3115
- } else {
3116
- println ! ( "Found param ty" ) ;
3117
- }
3118
-
3119
- }
3120
3074
3121
- if let hir:: Node :: Expr ( expr) = cx. tcx . hir_node ( * hir_id) {
3122
- Self :: maybe_lint_return_expr ( cx, expr, params) ;
3123
- }
3075
+ match return_expr {
3076
+ hir:: Expr { kind : hir:: ExprKind :: AddrOf ( _, _, addr_expr) , .. } => {
3077
+ Self :: maybe_lint_return_expr ( cx, addr_expr, params)
3078
+ }
3079
+ hir:: Expr {
3080
+ kind :
3081
+ hir:: ExprKind :: Cast (
3082
+ hir:: Expr { kind : hir:: ExprKind :: AddrOf ( _, _, addr_expr) , .. } ,
3083
+ _,
3084
+ ) ,
3085
+ ..
3086
+ } => Self :: maybe_lint_return_expr ( cx, addr_expr, params) ,
3087
+ hir:: Expr { kind : hir:: ExprKind :: Cast ( expr, _) , .. } => {
3088
+ Self :: maybe_lint_return_expr ( cx, expr, params)
3089
+ }
3090
+ hir:: Expr {
3091
+ kind :
3092
+ hir:: ExprKind :: Path (
3093
+ hir:: QPath :: Resolved ( _, hir:: Path { res : hir:: def:: Res :: Local ( _) , .. } ) ,
3094
+ ..,
3095
+ ) ,
3096
+ ..
3097
+ } => cx. emit_span_lint (
3098
+ RETURNING_POINTERS_TO_LOCAL_VARIABLES ,
3099
+ return_expr. span ,
3100
+ BuiltinReturningPointersToLocalVariables ,
3101
+ ) ,
3102
+ _ => ( ) ,
3124
3103
}
3125
3104
}
3126
3105
3106
+ fn expr_is_param < ' tcx > (
3107
+ typeck_results : & ty:: TypeckResults < ' tcx > ,
3108
+ expr : & hir:: Expr < ' tcx > ,
3109
+ params : & ' tcx [ hir:: Ty < ' tcx > ] ,
3110
+ ) -> bool {
3111
+ params
3112
+ . iter ( )
3113
+ . map ( |param| typeck_results. type_dependent_def_id ( param. hir_id ) )
3114
+ . collect :: < Vec < _ > > ( )
3115
+ . contains ( & typeck_results. type_dependent_def_id ( expr. hir_id ) )
3116
+ }
3117
+
3127
3118
/// Returns the enclosing block for a [hir::HirId], if available.
3128
3119
fn get_enclosing_block < ' tcx > (
3129
3120
cx : & LateContext < ' tcx > ,
0 commit comments