From e5007cf2e0f7e161ad1712f9e216aa3ea7af268c Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Wed, 4 Oct 2017 10:46:42 -0700 Subject: [PATCH] [linters] Do not report MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE for the loop indices Reviewed By: jvillard Differential Revision: D5964060 fbshipit-source-id: 5998eff --- infer/src/clang/CLintersContext.ml | 6 ++++-- infer/src/clang/CLintersContext.mli | 3 ++- infer/src/clang/ComponentKit.ml | 1 + infer/src/clang/cFrontend_checkers_main.ml | 9 +++++---- .../codetoanalyze/componentkit/TestIgnoreImports.mm | 3 +++ 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/infer/src/clang/CLintersContext.ml b/infer/src/clang/CLintersContext.ml index 21c26c8e6..9e2408bf1 100644 --- a/infer/src/clang/CLintersContext.ml +++ b/infer/src/clang/CLintersContext.ml @@ -25,7 +25,8 @@ type context = (** If inside an objc class, contains the objc class (impl or interface) decl. *) ; current_objc_class: Clang_ast_t.decl option ; et_evaluation_node: string option - ; if_context: if_context option } + ; if_context: if_context option + ; in_for_loop_declaration: bool } let empty translation_unit_context = { current_method= None @@ -35,7 +36,8 @@ let empty translation_unit_context = ; is_ck_translation_unit= false ; current_objc_class= None ; et_evaluation_node= None - ; if_context= None } + ; if_context= None + ; in_for_loop_declaration= false } let add_parent_method decl_opt parent_methods = match decl_opt with Some decl -> decl :: parent_methods | None -> parent_methods diff --git a/infer/src/clang/CLintersContext.mli b/infer/src/clang/CLintersContext.mli index 40f693687..12de82e64 100644 --- a/infer/src/clang/CLintersContext.mli +++ b/infer/src/clang/CLintersContext.mli @@ -25,7 +25,8 @@ type context = (** If inside an objc class, contains the objc class (impl or interface) decl. *) ; current_objc_class: Clang_ast_t.decl option ; et_evaluation_node: string option - ; if_context: if_context option } + ; if_context: if_context option + ; in_for_loop_declaration: bool } val empty : CFrontend_config.translation_unit_context -> context diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index cde7faf95..c55009ec2 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -126,6 +126,7 @@ let mutable_local_vars_advice context an = is_ck_context context an && not (CAst_utils.is_syntactically_global_var decl) && not (CAst_utils.is_static_local_var decl) && not is_const && not (is_of_whitelisted_type qual_type) && not decl_info.di_is_implicit + && not context.CLintersContext.in_for_loop_declaration in if condition then Some diff --git a/infer/src/clang/cFrontend_checkers_main.ml b/infer/src/clang/cFrontend_checkers_main.ml index b49116aa9..16076fae1 100644 --- a/infer/src/clang/cFrontend_checkers_main.ml +++ b/infer/src/clang/cFrontend_checkers_main.ml @@ -241,10 +241,11 @@ let rec do_frontend_checks_stmt (context: CLintersContext.context) (* distinguish between then and else branch as they need different context *) [ (context, [stmt1; stmt2; cond_stmt; inside_else_stmt]) ; (inside_if_stmt_context, [inside_if_stmt]) ] - (* given that this has not been translated, looking up for variables *) - (* inside leads to inconsistencies *) - | ObjCAtCatchStmt _ - -> [(context, [])] + | ForStmt (_, stmt1 :: stmts) + -> let inside_for_stmt_decl_context = + {context with CLintersContext.in_for_loop_declaration= true} + in + [(context, stmts); (inside_for_stmt_decl_context, [stmt1])] | _ -> [(context, snd (Clang_ast_proj.get_stmt_tuple stmt))] in diff --git a/infer/tests/build_systems/codetoanalyze/componentkit/TestIgnoreImports.mm b/infer/tests/build_systems/codetoanalyze/componentkit/TestIgnoreImports.mm index 6bf48b8e8..a141f888a 100644 --- a/infer/tests/build_systems/codetoanalyze/componentkit/TestIgnoreImports.mm +++ b/infer/tests/build_systems/codetoanalyze/componentkit/TestIgnoreImports.mm @@ -16,6 +16,9 @@ @implementation SomeClass + (instancetype) new { int i; // error + + for (int i = 0; i < 10; i++) { + } return nil; } @end