diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index f275ffd8f..0859e4023 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -48,9 +48,14 @@ let protect ~f ~recover ~pp_context (trans_unit_ctx: CFrontend_config.translatio in EventLogger.log caught_incorrect_assumption ; log_and_recover ~print:true "Known incorrect assumption in the frontend: %s@\n" e.msg - | CTrans_utils.Self.SelfClassException class_name -> + | CTrans_utils.Self.SelfClassException e -> (* FIXME(t21762295): we do not expect this to happen but it does *) - log_and_recover ~print:true "Unexpected SelfClassException %a@\n" Typ.Name.pp class_name + let caught_selfclass_exception = + Some (Typ.Name.to_string e.class_name) + |> caught_exception "SelfClassException" e.position e.source_range + in + EventLogger.log caught_selfclass_exception ; + log_and_recover ~print:true "Unexpected SelfClassException %a@\n" Typ.Name.pp e.class_name | exn -> let trace = Backtrace.get () in reraise_if exn ~f:(fun () -> diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index a78956e43..d0ee5afa7 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -135,8 +135,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s expressions, but we take the type and create a static method call from it. This is done in objcMessageExpr_trans. *) let exec_with_self_exception f trans_state stmt = - try f trans_state stmt with Self.SelfClassException class_name -> - let typ = Typ.mk (Tstruct class_name) in + try f trans_state stmt with Self.SelfClassException e -> + let typ = Typ.mk (Tstruct e.class_name) in { empty_res_trans with exps= [ ( Exp.Sizeof {typ; nbytes= None; dynamic_length= None; subtype= Subtype.exact} @@ -716,10 +716,13 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let var_exp = Exp.Lvar pvar in let exps = if Self.is_var_self pvar (CContext.is_objc_method context) then - let class_typename = CContext.get_curr_class_typename context in - if CType.is_class typ then raise (Self.SelfClassException class_typename) + let class_name = CContext.get_curr_class_typename context in + if CType.is_class typ then + raise + (Self.SelfClassException + {class_name; position= __POS__; source_range= stmt_info.Clang_ast_t.si_source_range}) else - let typ = CType.add_pointer_to_typ (Typ.mk (Tstruct class_typename)) in + let typ = CType.add_pointer_to_typ (Typ.mk (Tstruct class_name)) in [(var_exp, typ)] else [(var_exp, typ)] in @@ -1165,7 +1168,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s in (* alloc or new *) (* FIXME(t21762295): we do not expect this to propagate to the top but it does *) - raise (Self.SelfClassException class_name) + raise + (Self.SelfClassException + {class_name; position= __POS__; source_range= si.Clang_ast_t.si_source_range}) else if String.equal selector CFrontend_config.alloc || String.equal selector CFrontend_config.new_str then @@ -1190,11 +1195,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s try let fst_res_trans = instruction trans_state_param stmt in (obj_c_message_expr_info, fst_res_trans) - with Self.SelfClassException class_typename -> + with Self.SelfClassException e -> let pointer = obj_c_message_expr_info.Clang_ast_t.omei_decl_pointer in let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in let obj_c_message_expr_info = - Ast_expressions.make_obj_c_message_expr_info_class selector class_typename pointer + Ast_expressions.make_obj_c_message_expr_info_class selector e.class_name pointer in (obj_c_message_expr_info, empty_res_trans) in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 4fe74d1ff..53c6e7567 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -569,7 +569,10 @@ let extract_stmt_from_singleton stmt_list warning_string = module Self = struct - exception SelfClassException of Typ.Name.t + exception SelfClassException of + { class_name: Typ.Name.t + ; position: string * int * int * int + ; source_range: Clang_ast_t.source_range } let add_self_parameter_for_super_instance context procname loc mei = if is_superinstance mei then diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index 5c8e6ba1d..b2b4ed923 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -156,7 +156,10 @@ end (** This module handles the translation of the variable self which is challenging because self is used both as a variable in instance method calls and also as a type in class method calls. *) module Self : sig - exception SelfClassException of Typ.Name.t + exception SelfClassException of + { class_name: Typ.Name.t + ; position: string * int * int * int + ; source_range: Clang_ast_t.source_range } val add_self_parameter_for_super_instance : CContext.t -> Typ.Procname.t -> Location.t -> Clang_ast_t.obj_c_message_expr_info