[AL] Introduce a way of binding the two witnesses of an AND formula

Summary:
New syntax f1 AND-WITH-WITNESSES f2 : predicate_on_both_witnesses()

This is needed for a linter to check that a macro is present, see the test.

Reviewed By: skcho

Differential Revision: D18735988

fbshipit-source-id: a3be75c5e
master
Dulma Churchill 5 years ago committed by Facebook Github Bot
parent c9449cce77
commit 48da570aa0

@ -287,6 +287,9 @@ let rec apply_substitution f sub =
Not (apply_substitution f1 sub) Not (apply_substitution f1 sub)
| And (f1, f2) -> | And (f1, f2) ->
And (apply_substitution f1 sub, apply_substitution f2 sub) And (apply_substitution f1 sub, apply_substitution f2 sub)
| AndWithWitnesses (f1, f2, (name, ps)) ->
AndWithWitnesses
(apply_substitution f1 sub, apply_substitution f2 sub, (name, sub_list_param ps))
| Or (f1, f2) -> | Or (f1, f2) ->
Or (apply_substitution f1 sub, apply_substitution f2 sub) Or (apply_substitution f1 sub, apply_substitution f2 sub)
| Implies (f1, f2) -> | Implies (f1, f2) ->
@ -323,32 +326,40 @@ let expand_formula phi map_ error_msg_ =
in in
let open CTLTypes in let open CTLTypes in
let rec expand acc map error_msg = let rec expand acc map error_msg =
let expand_predicate av actual_param =
match av with
| ALVar.Formula_id name -> (
(* it may be a macro *)
let error_msg' = error_msg ^ " -Expanding formula identifier '" ^ name ^ "'@\n" in
try
match ALVar.FormulaIdMap.find av map with
| true, _, _ ->
fail_with_circular_macro_definition name error_msg'
| false, fparams, f1 -> (
(* in this case it should be a defined macro *)
match List.zip fparams actual_param with
| Ok sub ->
let f1_sub = apply_substitution f1 sub in
let map' = ALVar.FormulaIdMap.add av (true, fparams, f1) map in
expand f1_sub map' error_msg'
| Unequal_lengths ->
L.(die ExternalError)
"Formula identifier '%s' is not called with the right number of parameters" name
)
with Caml.Not_found -> acc )
(* in this case it should be a predicate *)
in
match acc with match acc with
| True | False -> | True | False ->
acc acc
| Atomic ((ALVar.Formula_id name as av), actual_param) -> ( | Atomic (av, actual_param) ->
(* it may be a macro *) expand_predicate av actual_param
let error_msg' = error_msg ^ " -Expanding formula identifier '" ^ name ^ "'@\n" in
try
match ALVar.FormulaIdMap.find av map with
| true, _, _ ->
fail_with_circular_macro_definition name error_msg'
| false, fparams, f1 -> (
(* in this case it should be a defined macro *)
match List.zip fparams actual_param with
| Ok sub ->
let f1_sub = apply_substitution f1 sub in
let map' = ALVar.FormulaIdMap.add av (true, fparams, f1) map in
expand f1_sub map' error_msg'
| Unequal_lengths ->
L.(die ExternalError)
"Formula identifier '%s' is not called with the right number of parameters" name )
with Caml.Not_found -> acc
(* in this case it should be a predicate *) )
| Not f1 -> | Not f1 ->
Not (expand f1 map error_msg) Not (expand f1 map error_msg)
| And (f1, f2) -> | And (f1, f2) ->
And (expand f1 map error_msg, expand f2 map error_msg) And (expand f1 map error_msg, expand f2 map error_msg)
| AndWithWitnesses (f1, f2, pred) ->
AndWithWitnesses (expand f1 map error_msg, expand f2 map error_msg, pred)
| Or (f1, f2) -> | Or (f1, f2) ->
Or (expand f1 map error_msg, expand f2 map error_msg) Or (expand f1 map error_msg, expand f2 map error_msg)
| Implies (f1, f2) -> | Implies (f1, f2) ->

@ -0,0 +1,27 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
let decl_name_is_contained_in_name_of_decl (node1 : Ctl_parser_types.ast_node)
(node2 : Ctl_parser_types.ast_node) =
let get_name decl =
match Clang_ast_proj.get_named_decl_tuple decl with
| Some (_, ndi) ->
Some ndi.ni_name
| None ->
None
in
match (node1, node2) with
| Decl decl1, Decl decl2 -> (
match (get_name decl1, get_name decl2) with
| Some name1, Some name2 ->
String.is_substring name2 ~substring:name1
| _ ->
false )
| _ ->
false

@ -1,13 +1,11 @@
/* (*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ *)
#import <Foundation/NSObject.h>
int x; open! IStd
@interface SiblingExample : NSObject val decl_name_is_contained_in_name_of_decl :
Ctl_parser_types.ast_node -> Ctl_parser_types.ast_node -> bool
@end

@ -513,7 +513,7 @@ let choose_witness_opt witness_opt1 witness_opt2 =
(* Evaluation of formulas *) (* Evaluation of formulas *)
(* evaluate an atomic formula (i.e. a predicate) on a ast node an and a (* evaluate an atomic formula (i.e. a predicate) on a ast node an and a
linter context lcxt. That is: an, lcxt |= pred_name(params) *) linter context lcxt. That is: an, lcxt |= pred_name(params) *)
let rec eval_Atomic pred_name_ args an lcxt = let eval_Atomic pred_name_ args an lcxt =
let pred_name = ALVar.formula_id_to_string pred_name_ in let pred_name = ALVar.formula_id_to_string pred_name_ in
match (pred_name, args, an) with match (pred_name, args, an) with
| "call_class_method", [m], an -> | "call_class_method", [m], an ->
@ -758,10 +758,44 @@ let rec eval_Atomic pred_name_ args an lcxt =
L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name
and eval_AND an lcxt f1 f2 = let eval_Atomic_with_witness pred_name_ args witness1 witness2 _ =
let pred_name = ALVar.formula_id_to_string pred_name_ in
match (pred_name, args) with
| "decl_name_is_contained_in_name_of_decl", [] ->
CPredicatesOnTwoNodes.decl_name_is_contained_in_name_of_decl witness1 witness2
| _ ->
L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name
let rec eval_AndWithW an lcxt f1 f2 =
match eval_formula f1 an lcxt with match eval_formula f1 an lcxt with
| Some witness1 -> ( | Some witness1 -> (
match eval_formula f2 an lcxt with match eval_formula ~keep_witness:true f2 an lcxt with
| Some witness2 ->
Some (witness1, witness2)
| _ ->
None )
| None (* we short-circuit the AND evaluation *) ->
None
and eval_AndWithWitnesses an lcxt f1 f2 pred_name_ args =
match eval_AndWithW an lcxt f1 f2 with
| Some (witness1, witness2) -> (
try if eval_Atomic_with_witness pred_name_ args witness1 witness2 lcxt then Some an else None
with CFrontend_errors.IncorrectAssumption e ->
let trans_unit_ctx = lcxt.CLintersContext.translation_unit_context in
ClangLogging.log_caught_exception trans_unit_ctx "IncorrectAssumption" e.position
e.source_range e.ast_node ;
None )
| None ->
None
and eval_AND ?keep_witness an lcxt f1 f2 =
match eval_formula ?keep_witness f1 an lcxt with
| Some witness1 -> (
match eval_formula ?keep_witness f2 an lcxt with
| Some witness2 -> | Some witness2 ->
Some (choose_one_witness witness1 witness2) Some (choose_one_witness witness1 witness2)
| _ -> | _ ->
@ -806,7 +840,7 @@ and eval_EF phi an lcxt trans =
there exists is a child an' of the node an there exists is a child an' of the node an
such that (an', lcxt) satifies phi such that (an', lcxt) satifies phi
*) *)
and eval_EX phi an lcxt trans = and eval_EX ?(keep_witness = false) phi an lcxt trans =
let succs = let succs =
match trans with match trans with
| Some l -> | Some l ->
@ -818,11 +852,13 @@ and eval_EX phi an lcxt trans =
List.fold_left succs ~init:None ~f:(fun acc node -> List.fold_left succs ~init:None ~f:(fun acc node ->
choose_witness_opt (eval_formula phi node lcxt) acc ) choose_witness_opt (eval_formula phi node lcxt) acc )
in in
match (witness_opt, trans) with if keep_witness then witness_opt
| Some _, Some trans when not (CTLTypes.is_transition_to_successor trans) -> else
Some an (* We want to limit the witnesses to the successors of the original node. *) match (witness_opt, trans) with
| _ -> | Some _, Some trans when not (CTLTypes.is_transition_to_successor trans) ->
witness_opt Some an (* We want to limit the witnesses to the successors of the original node. *)
| _ ->
witness_opt
(* an, lcxt |= E(phi1 U phi2) evaluated using the equivalence (* an, lcxt |= E(phi1 U phi2) evaluated using the equivalence
@ -917,7 +953,7 @@ and eval_InObjCClass an lcxt f1 f2 =
(* Formulas are evaluated on a AST node an and a linter context lcxt *) (* Formulas are evaluated on a AST node an and a linter context lcxt *)
and eval_formula f an lcxt : Ctl_parser_types.ast_node option = and eval_formula ?keep_witness f an lcxt : Ctl_parser_types.ast_node option =
let open CTLTypes in let open CTLTypes in
debug_eval_begin (debug_create_payload an f lcxt) ; debug_eval_begin (debug_create_payload an f lcxt) ;
let res = let res =
@ -939,6 +975,8 @@ and eval_formula f an lcxt : Ctl_parser_types.ast_node option =
match eval_formula f1 an lcxt with Some _ -> None | None -> Some an ) match eval_formula f1 an lcxt with Some _ -> None | None -> Some an )
| And (f1, f2) -> | And (f1, f2) ->
eval_AND an lcxt f1 f2 eval_AND an lcxt f1 f2
| AndWithWitnesses (f1, f2, (name, params)) ->
eval_AndWithWitnesses an lcxt f1 f2 name params
| Or (f1, f2) -> | Or (f1, f2) ->
eval_OR an lcxt f1 f2 eval_OR an lcxt f1 f2
| Implies (f1, f2) -> | Implies (f1, f2) ->
@ -954,7 +992,7 @@ and eval_formula f an lcxt : Ctl_parser_types.ast_node option =
| AG (trans, f1) -> | AG (trans, f1) ->
eval_formula (Not (EF (trans, Not f1))) an lcxt eval_formula (Not (EF (trans, Not f1))) an lcxt
| EX (trans, f1) -> | EX (trans, f1) ->
eval_EX f1 an lcxt trans eval_EX ?keep_witness f1 an lcxt trans
| AX (trans, f1) -> | AX (trans, f1) ->
eval_formula (Not (EX (trans, Not f1))) an lcxt eval_formula (Not (EX (trans, Not f1))) an lcxt
| EH (cl, phi) -> | EH (cl, phi) ->

@ -48,7 +48,8 @@ type al_file =
val print_checker : ctl_checker -> unit val print_checker : ctl_checker -> unit
val eval_formula : val eval_formula :
CTLTypes.t ?keep_witness:bool
-> CTLTypes.t
-> Ctl_parser_types.ast_node -> Ctl_parser_types.ast_node
-> CLintersContext.context -> CLintersContext.context
-> Ctl_parser_types.ast_node option -> Ctl_parser_types.ast_node option

@ -53,6 +53,7 @@ type t =
| Atomic of CPredicates.t | Atomic of CPredicates.t
| Not of t | Not of t
| And of t * t | And of t * t
| AndWithWitnesses of t * t * CPredicates.t
| Or of t * t | Or of t * t
| Implies of t * t | Implies of t * t
| InNode of ALVar.alexp list * t | InNode of ALVar.alexp list * t
@ -73,7 +74,17 @@ let equal = [%compare.equal: t]
let has_transition phi = let has_transition phi =
match phi with match phi with
| True | False | Atomic _ | Not _ | And _ | Or _ | Implies _ | InNode _ | EH _ | InObjCClass _ -> | True
| False
| Atomic _
| Not _
| And _
| Or _
| Implies _
| InNode _
| EH _
| InObjCClass _
| AndWithWitnesses _ ->
false false
| AX (trans_opt, _) | AX (trans_opt, _)
| AF (trans_opt, _) | AF (trans_opt, _)
@ -140,6 +151,11 @@ let rec pp_formula fmt phi =
| And (phi1, phi2) -> | And (phi1, phi2) ->
if full_print then Format.fprintf fmt "(%a AND %a)" pp_formula phi1 pp_formula phi2 if full_print then Format.fprintf fmt "(%a AND %a)" pp_formula phi1 pp_formula phi2
else Format.pp_print_string fmt "(... AND ...)" else Format.pp_print_string fmt "(... AND ...)"
| AndWithWitnesses (phi1, phi2, p) ->
if full_print then
Format.fprintf fmt "(%a AndWithWitnesses %a : %a)" pp_formula phi1 pp_formula phi2
CPredicates.pp_predicate p
else Format.pp_print_string fmt "(... AndWithWitnesses ...)"
| Or (phi1, phi2) -> | Or (phi1, phi2) ->
if full_print then Format.fprintf fmt "(%a OR %a)" pp_formula phi1 pp_formula phi2 if full_print then Format.fprintf fmt "(%a OR %a)" pp_formula phi1 pp_formula phi2
else Format.pp_print_string fmt "(... OR ...)" else Format.pp_print_string fmt "(... OR ...)"

@ -34,6 +34,7 @@ type t =
| Atomic of CPredicates.t (** Atomic formula *) | Atomic of CPredicates.t (** Atomic formula *)
| Not of t | Not of t
| And of t * t | And of t * t
| AndWithWitnesses of t * t * CPredicates.t
| Or of t * t | Or of t * t
| Implies of t * t | Implies of t * t
| InNode of ALVar.alexp list * t | InNode of ALVar.alexp list * t

@ -63,10 +63,12 @@ rule token = parse
| ")" { RIGHT_PAREN } | ")" { RIGHT_PAREN }
| "=" { ASSIGNMENT } | "=" { ASSIGNMENT }
| ";" { SEMICOLON } | ";" { SEMICOLON }
| ":" { COLON }
| "," { COMMA } | "," { COMMA }
| "[" { LEFT_SQBRACE } | "[" { LEFT_SQBRACE }
| "]" { RIGHT_SQBRACE } | "]" { RIGHT_SQBRACE }
| "AND" { AND } | "AND" { AND }
| "AND-WITH-WITNESSES" {AND_WITH_WITNESSES}
| "OR" { OR } | "OR" { OR }
| "NOT" { NOT } | "NOT" { NOT }
| "IMPLIES" { IMPLIES } | "IMPLIES" { IMPLIES }

@ -64,9 +64,11 @@
%token ASSIGNMENT %token ASSIGNMENT
%token SEMICOLON %token SEMICOLON
%token COMMA %token COMMA
%token COLON
%token LEFT_SQBRACE %token LEFT_SQBRACE
%token RIGHT_SQBRACE %token RIGHT_SQBRACE
%token AND %token AND
%token AND_WITH_WITNESSES
%token OR %token OR
%token NOT %token NOT
%token IMPLIES %token IMPLIES
@ -308,6 +310,9 @@ formula:
"\tParsed AX with transition '%a'@\n" CTLTypes.pp_transition $3; "\tParsed AX with transition '%a'@\n" CTLTypes.pp_transition $3;
CTLTypes.AX ($3, $4)} CTLTypes.AX ($3, $4)}
| formula AND formula { L.(debug Linters Verbose) "\tParsed AND@\n"; CTLTypes.And ($1, $3) } | formula AND formula { L.(debug Linters Verbose) "\tParsed AND@\n"; CTLTypes.And ($1, $3) }
| formula AND_WITH_WITNESSES formula COLON identifier LEFT_PAREN actual_params RIGHT_PAREN
{ L.(debug Linters Verbose) "\tParsed predicate@\n";
CTLTypes.AndWithWitnesses ($1, $3, (ALVar.Formula_id $5, $7)) }
| formula OR formula { L.(debug Linters Verbose) "\tParsed OR@\n"; CTLTypes.Or ($1, $3) } | formula OR formula { L.(debug Linters Verbose) "\tParsed OR@\n"; CTLTypes.Or ($1, $3) }
| formula IMPLIES formula | formula IMPLIES formula
{ L.(debug Linters Verbose) "\tParsed IMPLIES@\n"; CTLTypes.Implies ($1, $3) } { L.(debug Linters Verbose) "\tParsed IMPLIES@\n"; CTLTypes.Implies ($1, $3) }

@ -907,8 +907,30 @@ DEFINE-CHECKER CLASS_AND_VAR = {
(global_var_exists())); (global_var_exists()));
SET report_when = SET report_when =
WHEN var_decl() AND declaration_has_name("SiblingExample") WHEN (var_decl() AND declaration_has_name("SiblingExample"))
HOLDS-IN-NODE ObjCInterfaceDecl; HOLDS-IN-NODE ObjCInterfaceDecl;
SET message = "Found a global var next to a class"; SET message = "Found a global var next to a class";
};
DEFINE-CHECKER CAT_DECL_MACRO = {
LET is_linkable_var =
is_extern_var() AND
declaration_has_name(REGEXP("Linkable_.*")) AND
has_type("char");
LET var_decls =
HOLDS-NEXT WITH-TRANSITION Sibling
(is_node("VarDecl") AND is_linkable_var());
SET report_when =
WHEN
NOT (
is_node("ObjCCategoryDecl")
AND-WITH-WITNESSES var_decls() : decl_name_is_contained_in_name_of_decl()
)
HOLDS-IN-NODE ObjCCategoryDecl;
SET message = "A category is defined without the corrsponding macro";
}; };

@ -0,0 +1,24 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
int x;
@interface SiblingExample
@end
#define LINK_REQUIRE(NAME) \
extern char Linkable_##NAME; \
extern const void* const OS_WEAK OS_CONCAT(Link_, NAME); \
OS_USED const void* const OS_WEAK OS_CONCAT(Link_, NAME) = &Linkable_##NAME;
LINK_REQUIRE(SiblingExample_Cat2);
@interface SiblingExample (Cat2)
- (void)foo:(int)themeProvider;
@end

@ -16,10 +16,12 @@ codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMetho
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase::testView, 15, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase::testView, 15, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 12, TEST_IF_IS_PROTOCOL_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 12, TEST_IF_IS_PROTOCOL_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 19, TEST_IF_IS_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 19, TEST_IF_IS_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 29, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 29, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 29, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 29, TEST_IF_IS_CATEGORY_ON_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 29, TEST_IF_IS_CATEGORY_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 35, TEST_IF_IS_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 35, TEST_IF_IS_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 35, TEST_IF_IS_IMPLEMENTATION_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 35, TEST_IF_IS_IMPLEMENTATION_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_INTERFACE_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_INTERFACE_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, []
@ -28,6 +30,7 @@ codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_metho
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_ON_CLASS_NAMED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_INTERFACE_ON_SUBCLASS_OF, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_INTERFACE_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_ON_SUBCLASS_OF, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 189, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_SUBCLASS_OF, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 189, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_SUBCLASS_OF, no_bucket, WARNING, []
@ -227,8 +230,10 @@ codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::
codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 11, TEST_RETURN_METHOD, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 11, TEST_RETURN_METHOD, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_RETURN_METHOD, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_RETURN_METHOD, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 20, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, SiblingExample::foo, 22, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, CONST_NAMING, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 8, CONST_NAMING, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 8, CONST_NAMING, no_bucket, WARNING, []
@ -274,6 +279,13 @@ codetoanalyze/objc/linters-for-test-only/protocols.m, Linters_dummy_method, 12,
codetoanalyze/objc/linters-for-test-only/protocols.m, Linters_dummy_method, 15, TEST_PROTOCOL_DEF_INHERITANCE, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/protocols.m, Linters_dummy_method, 15, TEST_PROTOCOL_DEF_INHERITANCE, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithAction, 10, TEST_INSTANCE_TYPE, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithAction, 10, TEST_INSTANCE_TYPE, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithAction, 10, TEST_PARAMETER_SEL_TYPE, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithAction, 10, TEST_PARAMETER_SEL_TYPE, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 20, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 25, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 26, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 21, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 27, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_RETURN_METHOD, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_RETURN_METHOD, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 17, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 17, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []

@ -0,0 +1,29 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
int x;
@interface SiblingExample
@end
#define LINK_REQUIRE(NAME) \
extern char Linkable_##NAME; \
extern const void* const OS_WEAK OS_CONCAT(Link_, NAME); \
OS_USED const void* const OS_WEAK OS_CONCAT(Link_, NAME) = &Linkable_##NAME;
@interface SiblingExample (Cat1)
- (void)foo:(int)themeProvider;
@end
LINK_REQUIRE(SiblingExampl);
@interface SiblingExample (Cat2)
- (void)foo:(int)themeProvider;
@end
Loading…
Cancel
Save