[linters] Add logging and caught exceptions to the linters

Reviewed By: ddino

Differential Revision: D6899312

fbshipit-source-id: f063251
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent f1e01bdfc7
commit 8053734563

@ -0,0 +1,24 @@
(*
* Copyright (c) 2018 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! IStd
module F = Format
let log_caught_exception (trans_unit_ctx: CFrontend_config.translation_unit_context) exception_type
(exception_file, exception_line, _, _) (source_location_start, source_location_end) ast_node =
let caught_exception =
EventLogger.FrontendException
{ exception_type
; source_location_start= CLocation.clang_to_sil_location trans_unit_ctx source_location_start
; source_location_end= CLocation.clang_to_sil_location trans_unit_ctx source_location_end
; exception_file
; exception_line
; ast_node
; lang= CFrontend_config.string_of_clang_lang trans_unit_ctx.lang }
in
EventLogger.log caught_exception

@ -0,0 +1,14 @@
(*
* Copyright (c) 2018 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! IStd
val log_caught_exception :
CFrontend_config.translation_unit_context -> string -> CFrontend_config.ocaml_pos
-> Clang_ast_t.source_location * Clang_ast_t.source_location -> string option -> unit

@ -135,13 +135,14 @@ let get_enum_constant_exp enum_constant_pointer =
ClangPointers.Map.find_exn !CFrontend_config.enum_map enum_constant_pointer
let get_type type_ptr =
(* There is chance for success only if type_ptr is in fact clang pointer *)
let get_type ?source_range type_ptr =
let source_range = match source_range with Some sr -> sr | None -> dummy_source_range () in
match type_ptr with
(* There is chance for success only if type_ptr is in fact clang pointer *)
| Clang_ast_types.TypePtr.Ptr raw_ptr ->
let typ = Int.Table.find ClangPointers.pointer_type_table raw_ptr in
if Option.is_none typ then
CFrontend_config.incorrect_assumption __POS__ (dummy_source_range ())
CFrontend_config.incorrect_assumption __POS__ source_range
"type with pointer %d not found@\n" raw_ptr ;
typ
| _ ->
@ -151,8 +152,8 @@ let get_type type_ptr =
None
let get_desugared_type type_ptr =
let typ_opt = get_type type_ptr in
let get_desugared_type ?source_range type_ptr =
let typ_opt = get_type ?source_range type_ptr in
match typ_opt with
| Some typ
-> (

@ -52,10 +52,12 @@ val get_unqualified_name : Clang_ast_t.named_decl_info -> string
val get_class_name_from_member : Clang_ast_t.named_decl_info -> QualifiedCppName.t
(** returns qualified class name given member name info *)
val get_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
val get_type :
?source_range:Clang_ast_t.source_range -> Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
(** looks up clang pointer to type and returns c_type. It requires type_ptr to be `TPtr. *)
val get_desugared_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
val get_desugared_type :
?source_range:Clang_ast_t.source_range -> Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
(** looks up clang pointer to type and resolves any sugar around it.
See get_type for more info and restrictions *)

@ -20,9 +20,11 @@ let string_of_clang_lang (lang: clang_lang) : string =
let equal_clang_lang = [%compare.equal : clang_lang]
type ocaml_pos = string * int * int * int
type exception_details =
{ msg: string
; position: string * int * int * int
; position: ocaml_pos
; source_range: Clang_ast_t.source_range
; ast_node: string option }
@ -37,7 +39,6 @@ exception IncorrectAssumption of exception_details
let incorrect_assumption position source_range ?ast_node fmt =
F.kasprintf (fun msg -> raise (IncorrectAssumption {msg; position; source_range; ast_node})) fmt
type translation_unit_context = {lang: clang_lang; source_file: SourceFile.t}
(** Constants *)

@ -17,16 +17,18 @@ val string_of_clang_lang : clang_lang -> string
val equal_clang_lang : clang_lang -> clang_lang -> bool
type ocaml_pos = string * int * int * int
type exception_details =
{ msg: string
; position: string * int * int * int
; position: ocaml_pos
; source_range: Clang_ast_t.source_range
; ast_node: string option }
exception Unimplemented of exception_details
val unimplemented :
string * int * int * int -> Clang_ast_t.source_range -> ?ast_node:string
ocaml_pos -> Clang_ast_t.source_range -> ?ast_node:string
-> ('a, Format.formatter, unit, _) format4 -> 'a
(** Raise Unimplemented. This is caught at the level of translating a method and makes the frontend
give up on that method. *)
@ -34,7 +36,7 @@ val unimplemented :
exception IncorrectAssumption of exception_details
val incorrect_assumption :
string * int * int * int -> Clang_ast_t.source_range -> ?ast_node:string
ocaml_pos -> Clang_ast_t.source_range -> ?ast_node:string
-> ('a, Format.formatter, unit, _) format4 -> 'a
(** Used to mark places in the frontend that incorrectly assume something to be
impossible. TODO(t21762295) get rid of all instances of this. *)

@ -20,41 +20,24 @@ let protect ~f ~recover ~pp_context (trans_unit_ctx: CFrontend_config.translatio
incr CFrontend_config.procedures_failed ;
(if print then L.internal_error else L.(debug Capture Quiet)) ("%a@\n" ^^ fmt) pp_context ()
in
let caught_exception exception_type (exception_file, exception_line, _, _)
(source_location_start, source_location_end) ast_node =
EventLogger.FrontendException
{ exception_type
; source_location_start= CLocation.clang_to_sil_location trans_unit_ctx source_location_start
; source_location_end= CLocation.clang_to_sil_location trans_unit_ctx source_location_end
; exception_file
; exception_line
; ast_node
; lang= CFrontend_config.string_of_clang_lang trans_unit_ctx.lang }
in
try f () with
(* Always keep going in case of known limitations of the frontend, crash otherwise (by not
catching the exception) unless `--keep-going` was passed. Print errors we should fix
(t21762295) to the console. *)
| CFrontend_config.Unimplemented e ->
let caught_unimplemented_exception =
caught_exception "Unimplemented" e.position e.source_range e.ast_node
in
EventLogger.log caught_unimplemented_exception ;
ClangLogging.log_caught_exception trans_unit_ctx "Unimplemented" e.position e.source_range
e.ast_node ;
log_and_recover ~print:false "Unimplemented feature:@\n %s@\n" e.msg
| CFrontend_config.IncorrectAssumption e ->
(* FIXME(t21762295): we do not expect this to happen but it does *)
let caught_incorrect_assumption =
caught_exception "IncorrectAssumption" e.position e.source_range e.ast_node
in
EventLogger.log caught_incorrect_assumption ;
ClangLogging.log_caught_exception trans_unit_ctx "IncorrectAssumption" e.position
e.source_range e.ast_node ;
log_and_recover ~print:true "Known incorrect assumption in the frontend: %s@\n" e.msg
| CTrans_utils.Self.SelfClassException e ->
(* FIXME(t21762295): we do not expect this to happen but it does *)
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 ;
|> ClangLogging.log_caught_exception trans_unit_ctx "SelfClassException" e.position
e.source_range ;
log_and_recover ~print:true "Unexpected SelfClassException %a@\n" Typ.Name.pp e.class_name
| exn ->
let trace = Backtrace.get () in

@ -708,7 +708,11 @@ let has_type_const_ptr_to_objc_class node =
let open Clang_ast_t in
match get_ast_node_type_ptr node with
| Some type_ptr -> (
match CAst_utils.get_desugared_type type_ptr with
match
CAst_utils.get_desugared_type
~source_range:(Ctl_parser_types.ast_node_source_range node)
type_ptr
with
| Some ObjCObjectPointerType (_, qt) ->
qt.qt_is_const
| _ ->

@ -1209,8 +1209,13 @@ and eval_formula f an lcxt : Ctl_parser_types.ast_node option =
Some an
| False ->
None
| Atomic (name, params) ->
if eval_Atomic name params an lcxt then Some an else None
| Atomic (name, params) -> (
try if eval_Atomic name params an lcxt then Some an else None
with CFrontend_config.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 )
| InNode (node_type_list, f1) ->
in_node node_type_list f1 an lcxt
| Not f1 -> (

@ -90,6 +90,16 @@ let ast_node_kind node =
Clang_ast_proj.get_decl_kind_string decl
let ast_node_source_range node =
match node with
| Stmt stmt ->
let s_stmt_info, _ = Clang_ast_proj.get_stmt_tuple stmt in
s_stmt_info.si_source_range
| Decl decl ->
let d_decl_info = Clang_ast_proj.get_decl_tuple decl in
d_decl_info.di_source_range
(* true iff an ast node is a node of type among the list tl *)
let ast_node_has_kind tl an =
let an_alexp = ALVar.Const (ast_node_kind an) in

@ -31,6 +31,8 @@ val stmt_node_child_type : ast_node -> string
val ast_node_cast_kind : ast_node -> string
val ast_node_source_range : ast_node -> Clang_ast_t.source_range
val is_node_successor_of : is_successor:ast_node -> ast_node -> bool
val get_direct_successor_nodes : ast_node -> ast_node list

Loading…
Cancel
Save