diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 61203dc14..4478437d7 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1180,11 +1180,10 @@ and iphoneos_target_sdk_version = ~in_help:CLOpt.([(Capture, manual_clang_linters)]) "Specify the target SDK version to use for iphoneos" -and iphoneos_target_sdk_version_skip_path = - CLOpt.mk_string_list ~long:"iphoneos-target-sdk-version-skip-path" +and iphoneos_target_sdk_version_path_regex = + CLOpt.mk_string_list ~long:"iphoneos-target-sdk-version-path-regex" ~in_help:CLOpt.([(Capture, manual_clang_linters)]) - ~meta:"path_prefix_OCaml_regex" - "To be used together with iphoneos-target-sdk-version, to disable that flag in a particular path (can be specified multiple times)" + "To pass a specific target SDK version to use for iphoneos in a particular path, with the format path:version (can be specified multiple times)" and issues_fields = CLOpt.mk_symbol_seq ~long:"issues-fields" @@ -1840,6 +1839,20 @@ let command, parse_args_and_return_usage_exit = let print_usage_exit () = parse_args_and_return_usage_exit 1 +type iphoneos_target_sdk_version_path_regex = {path: Str.regexp; version: string} + +let process_iphoneos_target_sdk_version_path_regex args = + let process_iphoneos_target_sdk_version_path_regex arg : iphoneos_target_sdk_version_path_regex = + match String.rsplit2 ~on:':' arg with + | Some (path, version) + -> {path= Str.regexp path; version} + | None + -> failwithf + "Incorrect format for the option iphoneos-target-sdk_version-path-regex. The correct format is path:version but got %s" + arg + in + List.map ~f:process_iphoneos_target_sdk_version_path_regex args + (** Freeze initialized configuration values *) let anon_args = !anon_args @@ -2023,7 +2036,8 @@ and infer_cache = !infer_cache and iphoneos_target_sdk_version = !iphoneos_target_sdk_version -and iphoneos_target_sdk_version_skip_path = !iphoneos_target_sdk_version_skip_path +and iphoneos_target_sdk_version_path_regex = + process_iphoneos_target_sdk_version_path_regex !iphoneos_target_sdk_version_path_regex and issues_fields = !issues_fields diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index f41c8ff03..22b5a96b8 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -424,7 +424,9 @@ val infer_cache : string option val iphoneos_target_sdk_version : string option -val iphoneos_target_sdk_version_skip_path : string list +type iphoneos_target_sdk_version_path_regex = {path: Str.regexp; version: string} + +val iphoneos_target_sdk_version_path_regex : iphoneos_target_sdk_version_path_regex list val issues_fields : [ `Issue_field_bug_class diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 46df3e56a..aab762c1c 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -492,25 +492,21 @@ let is_class an re = | _ -> false -let should_use_iphoneos_target_sdk_version = - let f = - ( lazy - ( match Config.iphoneos_target_sdk_version_skip_path with - | [] - -> fun _ -> true - | _ :: _ as skip_paths - -> (* pre-compute the regexp because it is expensive *) - let paths_regexp = String.concat ~sep:"\\|" skip_paths |> Str.regexp in - (* return a closure so that the regexp is computed only once *) - fun {CLintersContext.translation_unit_context= {source_file}} -> - not (ALVar.str_match_forward (SourceFile.to_rel_path source_file) paths_regexp) ) ) +let iphoneos_target_sdk_version_by_path (cxt: CLintersContext.context) = + let source_file = cxt.translation_unit_context.source_file in + let regex_version_opt = + List.find Config.iphoneos_target_sdk_version_path_regex ~f: + (fun (version_path_regex: Config.iphoneos_target_sdk_version_path_regex) -> + ALVar.str_match_forward (SourceFile.to_rel_path source_file) version_path_regex.path ) in - fun ctx -> Lazy.force f ctx + match regex_version_opt with + | Some version_by_regex + -> Some version_by_regex.version + | None (* no version by path specified, use default version *) + -> Config.iphoneos_target_sdk_version let decl_unavailable_in_supported_ios_sdk (cxt: CLintersContext.context) an = - let config_iphoneos_target_sdk_version = - if should_use_iphoneos_target_sdk_version cxt then Config.iphoneos_target_sdk_version else None - in + let config_iphoneos_target_sdk_version = iphoneos_target_sdk_version_by_path cxt in let allowed_os_versions = match (config_iphoneos_target_sdk_version, (cxt.if_context : CLintersContext.if_context option)) diff --git a/infer/tests/codetoanalyze/objc/ioslints/Makefile b/infer/tests/codetoanalyze/objc/ioslints/Makefile index 64b6be192..658ae508d 100644 --- a/infer/tests/codetoanalyze/objc/ioslints/Makefile +++ b/infer/tests/codetoanalyze/objc/ioslints/Makefile @@ -18,7 +18,7 @@ CLANG_OPTIONS = -x objective-c \ ANALYZER = linters INFER_OPTIONS = --no-filtering --debug-exceptions --project-root $(TESTS_DIR) \ --iphoneos-target-sdk-version 8.0 \ ---iphoneos-target-sdk-version-skip-path "codetoanalyze/objc/ioslints/filter_out_unavailable_api\.m" \ +--iphoneos-target-sdk-version-path-regex "codetoanalyze/objc/ioslints/filter_out_unavailable_api\.m:10.0" \ --no-keep-going INFERPRINT_OPTIONS = --issues-tests