diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 310c6a47c..20e32ef67 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -252,6 +252,29 @@ let is_enum_constant an name = | _ -> false +let is_enum_constant_of_enum an name = + match an with + | Ctl_parser_types.Stmt Clang_ast_t.DeclRefExpr (_, _, _, drti) -> ( + match drti.drti_decl_ref with + | Some dr + -> ( + let ndi, _, _ = CAst_utils.get_info_from_decl_ref dr in + let qual_name = CAst_utils.get_qualified_name ndi in + match QualifiedCppName.extract_last qual_name with + | Some (_, stripped_qual_name) -> ( + match QualifiedCppName.extract_last stripped_qual_name with + | Some (enum_name, _) + -> PVariant.( = ) dr.Clang_ast_t.dr_kind `EnumConstant + && ALVar.compare_str_with_alexp enum_name name + | _ + -> false ) + | _ + -> false ) + | _ + -> false ) + | _ + -> false + let is_strong_property an = match an with | Ctl_parser_types.Decl Clang_ast_t.ObjCPropertyDecl (_, _, pdi) diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index ae60a8369..dde3f7995 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -25,6 +25,8 @@ val declaration_name : Clang_ast_t.decl -> string option val is_enum_constant : Ctl_parser_types.ast_node -> ALVar.alexp -> bool +val is_enum_constant_of_enum : Ctl_parser_types.ast_node -> ALVar.alexp -> bool + val is_objc_interface_named : Ctl_parser_types.ast_node -> ALVar.alexp -> bool val is_objc_extension : CLintersContext.context -> bool diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 5e3405383..6979eb9b5 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -796,6 +796,8 @@ let rec eval_Atomic _pred_name args an lcxt = -> CPredicates.is_const_expr_var an | "is_enum_constant", [cname], an -> CPredicates.is_enum_constant an cname + | "is_enum_constant_of_enum", [name], an + -> CPredicates.is_enum_constant_of_enum an name | "is_global_var", [], an -> CPredicates.is_syntactically_global_var an | "is_in_block", [], _ diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/enums.m b/infer/tests/codetoanalyze/objc/linters-for-test-only/enums.m index 7678dfe86..337cb3d2a 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/enums.m +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/enums.m @@ -11,10 +11,13 @@ typedef NS_ENUM(NSUInteger, MyName) { MyNameUndefined, + MyNameDefined, }; int test() { return MyNameUndefined; } +int test_enum_constant_of_enum() { return MyNameDefined; } + enum { RANDOM, IMMEDIATE, SEARCH } strategy; int test_c_style_enum() { return IMMEDIATE; } diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp index 4a28438d3..cc1ee2b9a 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -9,8 +9,11 @@ codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, function, 27, codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methodd, 16, TEST_BUILTIN_TYPE, [] codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methoddd, 20, TEST_BUILTIN_TYPE, [] codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methoddd, 21, TEST_SELECTOR, [] -codetoanalyze/objc/linters-for-test-only/enums.m, test, 16, ENUM_CONSTANTS, [] -codetoanalyze/objc/linters-for-test-only/enums.m, test_c_style_enum, 20, ENUM_CONSTANTS, [] +codetoanalyze/objc/linters-for-test-only/enums.m, test, 17, ENUM_CONSTANTS, [] +codetoanalyze/objc/linters-for-test-only/enums.m, test, 17, ENUM_CONSTANTS_OF_ENUM, [] +codetoanalyze/objc/linters-for-test-only/enums.m, test_c_style_enum, 23, ENUM_CONSTANTS, [] +codetoanalyze/objc/linters-for-test-only/enums.m, test_enum_constant_of_enum, 19, ENUM_CONSTANTS, [] +codetoanalyze/objc/linters-for-test-only/enums.m, test_enum_constant_of_enum, 19, ENUM_CONSTANTS_OF_ENUM, [] codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, ALL_PATH_NO_FILTER_EXAMPLE, [] codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, FILTER_BY_ALL_PATH_EXAMPLE, [] codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, FILTER_BY_PATH_EXAMPLE, [] diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al index da9ac92b3..a92bb504b 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al @@ -344,6 +344,11 @@ DEFINE-CHECKER ENUM_CONSTANTS = { SET message = "Do not use the enum MyName or strategy"; }; +DEFINE-CHECKER ENUM_CONSTANTS_OF_ENUM = { + SET report_when = is_enum_constant_of_enum("MyName"); + SET message = "Do not use the enum MyName"; +}; + DEFINE-CHECKER TEST_SELECTOR = { SET report_when = is_at_selector_with_name("actionButtonTapped:"); SET message = "Found @selector(actionButtonTapped:)";