[clang] distinguish genuine internal failures from unimplemented features

Summary:
The clang frontend uses `assert false` for unimplemented features that should
abort method translations, as well as for genuine internal errors.
Distinguishing between the two, we can fail hard on the latter and not the
former.

1. This introduces a new exception `Unimplemented` that is used instead of `assert false` where appropriate.
2. Changed some other cases into `die ...` (when there's an error message to display)
3. Wherever a path in the code that we assumed to be unreachable was observed reachable, we now raise `IncorrectAssumption`. These should be fixed, but the fixes are not obvious.

Reviewed By: sblackshear

Differential Revision: D5784384

fbshipit-source-id: 61b55af
master
Jules Villard 7 years ago committed by Facebook Github Bot
parent faf04af1f4
commit 2fff3b0733

@ -138,6 +138,8 @@ let elapsed_time fmt () =
let string fmt s = F.fprintf fmt "%s" s
let option pp fmt = function None -> string fmt "None" | Some x -> F.fprintf fmt "Some %a" pp x
let to_string ~f fmt x = string fmt (f x)
let pp_argfile fmt fname =

@ -68,6 +68,8 @@ val latex : color -> env
val color_string : color -> string
(** string representation of colors *)
val option : (F.formatter -> 'a -> unit) -> F.formatter -> 'a option -> unit
val string : F.formatter -> string -> unit
val cli_args : F.formatter -> string list -> unit

@ -15,25 +15,13 @@ let debug_mode = Config.debug_mode || Config.frontend_stats
let buffer_len = 262143
let catch_biniou_buffer_errors f x =
try[@warning "-52"] f x
with
| Invalid_argument
(* suppress warning: allow this one case because we're just reraising the error with another
error message so it doesn't really matter if this eventually fails *)
"Bi_inbuf.refill_from_channel"
->
L.external_error "WARNING: biniou buffer too short, skipping the file@\n" ;
assert false
(* This function reads the json file in fname, validates it, and encoded in the AST data structure
defined in Clang_ast_t. *)
let validate_decl_from_file fname =
catch_biniou_buffer_errors (Ag_util.Biniou.from_file ~len:buffer_len Clang_ast_b.read_decl) fname
Ag_util.Biniou.from_file ~len:buffer_len Clang_ast_b.read_decl fname
let validate_decl_from_channel chan =
catch_biniou_buffer_errors (Ag_util.Biniou.from_channel ~len:buffer_len Clang_ast_b.read_decl)
chan
Ag_util.Biniou.from_channel ~len:buffer_len Clang_ast_b.read_decl chan
let register_perf_stats_report source_file =
let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name in

@ -229,7 +229,8 @@ let make_next_object_exp stmt_info item items =
let decl_ref_expr_info = make_decl_ref_expr_info decl_ref in
(Clang_ast_t.DeclRefExpr (stmt_info_var, [], expr_info, decl_ref_expr_info), var_qual_type)
| _
-> assert false
-> CFrontend_config.incorrect_assumption "unexpected item %a"
(Pp.to_string ~f:Clang_ast_j.string_of_stmt) item
in
let message_call =
make_message_expr create_id_type CFrontend_config.next_object items stmt_info false
@ -582,7 +583,10 @@ let translate_block_enumerate block_name stmt_info stmt_list ei =
; free_stop ]
, op )
| _
-> assert false
-> (* FIXME(t21762295) this is reachable *)
CFrontend_config.incorrect_assumption "wrong params in block enumerate translation: %a"
(Pp.seq (Pp.to_string ~f:Clang_ast_j.string_of_decl))
params
in
let open Clang_ast_t in
match stmt_list with

@ -301,36 +301,32 @@ let do_frontend_checks (trans_unit_ctx: CFrontend_config.translation_unit_contex
"Loading the following linters files: %a@\n" (Pp.comma_seq Format.pp_print_string)
linters_files ;
CTL.create_ctl_evaluation_tracker trans_unit_ctx.source_file ;
try
let parsed_linters = parse_ctl_files linters_files in
let filtered_parsed_linters =
CFrontend_errors.filter_parsed_linters parsed_linters trans_unit_ctx.source_file
in
CFrontend_errors.parsed_linters := filtered_parsed_linters ;
let source_file = trans_unit_ctx.CFrontend_config.source_file in
L.(debug Linters Medium)
"Start linting file %a with rules: @\n%a@\n" SourceFile.pp source_file
let parsed_linters = parse_ctl_files linters_files in
let filtered_parsed_linters =
CFrontend_errors.filter_parsed_linters parsed_linters trans_unit_ctx.source_file
in
CFrontend_errors.parsed_linters := filtered_parsed_linters ;
let source_file = trans_unit_ctx.CFrontend_config.source_file in
L.(debug Linters Medium)
"Start linting file %a with rules: @\n%a@\n" SourceFile.pp source_file
CFrontend_errors.pp_linters filtered_parsed_linters ;
if Config.print_active_checkers then
L.progress "Linting file %a, active linters: @\n%a@\n" SourceFile.pp source_file
CFrontend_errors.pp_linters filtered_parsed_linters ;
if Config.print_active_checkers then
L.progress "Linting file %a, active linters: @\n%a@\n" SourceFile.pp source_file
CFrontend_errors.pp_linters filtered_parsed_linters ;
match ast with
| Clang_ast_t.TranslationUnitDecl (_, decl_list, _, _)
-> let context = context_with_ck_set (CLintersContext.empty trans_unit_ctx) decl_list in
let is_decl_allowed decl =
let decl_info = Clang_ast_proj.get_decl_tuple decl in
CLocation.should_do_frontend_check trans_unit_ctx decl_info.Clang_ast_t.di_source_range
in
let allowed_decls = List.filter ~f:is_decl_allowed decl_list in
(* We analyze the top level and then all the allowed declarations *)
CFrontend_errors.invoke_set_of_checkers_on_node context (Ctl_parser_types.Decl ast) ;
List.iter ~f:(do_frontend_checks_decl context) allowed_decls ;
if LintIssues.exists_issues () then store_issues source_file ;
L.(debug Linters Medium) "End linting file %a@\n" SourceFile.pp source_file ;
CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file
| _
-> assert false
(* NOTE: Assumes that an AST always starts with a TranslationUnitDecl *)
with Assert_failure (file, line, column) as exn ->
L.internal_error "Fatal error: exception Assert_failure(%s, %d, %d)@\n%!" file line column ;
reraise exn
match ast with
| Clang_ast_t.TranslationUnitDecl (_, decl_list, _, _)
-> let context = context_with_ck_set (CLintersContext.empty trans_unit_ctx) decl_list in
let is_decl_allowed decl =
let decl_info = Clang_ast_proj.get_decl_tuple decl in
CLocation.should_do_frontend_check trans_unit_ctx decl_info.Clang_ast_t.di_source_range
in
let allowed_decls = List.filter ~f:is_decl_allowed decl_list in
(* We analyze the top level and then all the allowed declarations *)
CFrontend_errors.invoke_set_of_checkers_on_node context (Ctl_parser_types.Decl ast) ;
List.iter ~f:(do_frontend_checks_decl context) allowed_decls ;
if LintIssues.exists_issues () then store_issues source_file ;
L.(debug Linters Medium) "End linting file %a@\n" SourceFile.pp source_file ;
CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file
| _
-> (* NOTE: Assumes that an AST always starts with a TranslationUnitDecl *)
assert false

@ -8,9 +8,18 @@
*)
open! IStd
module F = Format
(** Module that contains constants and global state used in the frontend *)
exception IncorrectAssumption of string
let incorrect_assumption fmt = F.kasprintf (fun msg -> raise (IncorrectAssumption msg)) fmt
exception Unimplemented of string
let unimplemented fmt = F.kasprintf (fun msg -> raise (Unimplemented msg)) fmt
type clang_lang = C | CPP | ObjC | ObjCPP [@@deriving compare]
let equal_clang_lang = [%compare.equal : clang_lang]

@ -11,6 +11,18 @@ open! IStd
(** Module that contains constants and global state used in the frontend *)
exception IncorrectAssumption of string
val incorrect_assumption : ('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. *)
exception Unimplemented of string
val unimplemented : ('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. *)
type clang_lang = C | CPP | ObjC | ObjCPP [@@deriving compare]
val equal_clang_lang : clang_lang -> clang_lang -> bool

@ -19,12 +19,14 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
(* Translates the method/function's body into nodes of the cfg. *)
let add_method trans_unit_ctx tenv cg cfg class_decl_opt procname body has_return_param
is_objc_method outer_context_opt extra_instrs =
let handle_translation_failure () =
L.(debug Capture Verbose)
"@\n@\n>>---------- ADDING METHOD: '%a' ---------<<@\n@\n" Typ.Procname.pp procname ;
let handle_frontend_failure ~print fmt =
Cfg.remove_proc_desc cfg procname ;
CMethod_trans.create_external_procdesc cfg procname is_objc_method None
CMethod_trans.create_external_procdesc cfg procname is_objc_method None ;
(if print then L.internal_error else L.(debug Capture Quiet))
("Aborting translation of method '%a':@\n" ^^ fmt) Typ.Procname.pp procname
in
L.(debug Capture Verbose)
"@\n@\n>>---------- ADDING METHOD: '%s' ---------<<@\n@." (Typ.Procname.to_string procname) ;
try
match Cfg.find_proc_desc_from_name cfg procname with
| Some procdesc
@ -48,22 +50,21 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
| None
-> ()
with
| Not_found
-> ()
| CTrans_utils.Self.SelfClassException _
-> (* this shouldn't happen, because self or [a class] should always be arguments of
functions. This is to make sure I'm not wrong. *)
assert false
| CTrans_utils.TemplatedCodeException _
-> L.internal_error "Fatal error: frontend doesn't support translation of templated code@\n" ;
handle_translation_failure ()
| CTrans_utils.UnsupportedStatementException stmt when Config.keep_going
-> L.internal_error "Unimplemented: translation for statement %s"
(Clang_ast_proj.get_stmt_kind_string stmt) ;
handle_translation_failure ()
| Assert_failure (file, line, column) when Config.keep_going
-> L.internal_error "Fatal error: exception Assert_failure(%s, %d, %d)@\n%!" file line column ;
handle_translation_failure ()
(* 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 msg
-> handle_frontend_failure ~print:false "Unimplemented feature:@\n %s@\n" msg
| CFrontend_config.IncorrectAssumption msg
-> (* FIXME(t21762295): we do not expect this to happen but it does *)
handle_frontend_failure ~print:true "Known incorrect assumption in the frontend: %s@\n" msg
| CTrans_utils.Self.SelfClassException class_name
-> (* FIXME(t21762295): we do not expect this to happen but it does *)
handle_frontend_failure ~print:true "Unexpected SelfClassException %a@\n" Typ.Name.pp
class_name
| exn when Config.keep_going
-> handle_frontend_failure ~print:true "Frontend error: %a@\nBacktrace:@\n%s" Exn.pp exn
(Exn.backtrace ())
let function_decl trans_unit_ctx tenv cfg cg func_decl block_data_opt =
let captured_vars, outer_context_opt =

@ -118,8 +118,7 @@ let evaluate_place_holder context ph an =
| "%name%"
-> MF.monospaced_to_string (Ctl_parser_types.ast_node_name an)
| _
-> L.internal_error "ERROR: helper function %s is unknown. Stop.@\n" ph ;
assert false
-> L.die InternalError "helper function %s is unknown" ph
(* given a message this function searches for a place-holder identifier,
eg %id%. Then it evaluates id and replaces %id% in message
@ -156,8 +155,7 @@ let string_to_err_kind = function
| "LIKE"
-> Exceptions.Klike
| s
-> L.internal_error "@\n[ERROR] Severity %s does not exist. Stop.@\n" s ;
assert false
-> L.die InternalError "Severity %s does not exist" s
let string_to_issue_mode m =
match m with
@ -166,8 +164,7 @@ let string_to_issue_mode m =
| "OFF"
-> CIssue.Off
| s
-> L.internal_error "@\n[ERROR] Mode %s does not exist. Please specify ON/OFF@\n" s ;
assert false
-> L.die InternalError "Mode %s does not exist. Please specify ON/OFF" s
let post_process_linter_definition (linter: linter) =
match

@ -656,19 +656,13 @@ let get_procname_from_cpp_lambda context dec =
-> let name_info, decl_ptr, _ = CAst_utils.get_info_from_decl_ref dr in
create_procdesc_with_pointer context decl_ptr None name_info.ni_name
| _
-> (* We should not get here *) assert false )
-> assert false )
| _
-> (* We should not get here *) assert false
-> assert false
let get_captures_from_cpp_lambda dec =
match dec with
| Clang_ast_t.CXXRecordDecl (_, _, _, _, _, _, _, cxx_rdi)
-> cxx_rdi.xrdi_lambda_captures
| _
-> (* We should not get here *) assert false
(*
let instance_to_method_call_type instance =
if instance then MCVirtual
else MCStatic
*)
-> assert false

@ -59,7 +59,6 @@ type t =
| EH of ALVar.alexp list * t
| ET of ALVar.alexp list * transitions option * t
let has_transition phi =
match phi with
| True
@ -609,7 +608,9 @@ let transition_decl_to_stmt d trs =
| InitExpr, CXXConstructorDecl _
| InitExpr, CXXConversionDecl _
| InitExpr, CXXDestructorDecl _
-> assert false (* to be done. Requires extending to lists *)
-> (* requires extending to lists *)
CFrontend_config.unimplemented
"transition_decl_to_stmt: InitExpr/CXX{Method,Constructor,Conversion,Destructor}"
| InitExpr, EnumConstantDecl (_, _, _, ecdi)
-> ecdi.ecdi_init_expr
| _, _

@ -454,7 +454,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let exps = [(exp, typ)] in
{empty_res_trans with exps; instrs}
| Tfun _ | Tvoid | Tarray _ | TVar _
-> assert false
-> CFrontend_config.unimplemented "fill_typ_with_zero on type %a" (Typ.pp Pp.text) typ
in
let res_trans = fill_typ_with_zero var_exp_typ in
{res_trans with initd_exps= [fst var_exp_typ]}
@ -572,9 +572,12 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
-> CType_decl.get_record_typename ~tenv:context.tenv decl
| _
-> assert false )
| _
-> assert false
(* di_parent_pointer should be always set for fields/ivars *)
| _ as decl
-> (* FIXME(t21762295): we do not expect this to happen but it does *)
CFrontend_config.incorrect_assumption
"di_parent_pointer should be always set for fields/ivars, but got %a"
(Pp.option (Pp.to_string ~f:Clang_ast_j.string_of_decl))
decl
in
let field_name = CGeneral_utils.mk_class_field_name class_tname field_string in
let field_exp = Exp.Lfield (obj_sil, field_name, class_typ) in
@ -844,8 +847,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
match stmt_list with
| [a; i]
-> (a, i)
(* Assumption: the statement list contains 2 elements,
the first is the array expr and the second the index *)
(* Assumption: the statement list contains 2 elements, the first is the array expr and the
second the index *)
| _
-> assert false
(* Let's get notified if the assumption is wrong...*)
@ -1013,9 +1016,14 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let act_params =
let params = List.tl_exn (collect_exprs result_trans_subexprs) in
if Int.equal (List.length params) (List.length params_stmt) then params
else (
L.internal_error "ERROR: stmt_list and res_trans_par.exps must have same size@\n" ;
assert false )
else
(* FIXME(t21762295) this is reachable *)
CFrontend_config.incorrect_assumption
"In call to %a: stmt_list and res_trans_par.exps must have same size but they don't:@\nstmt_list(%d)=[%a]@\nres_trans_par.exps(%d)=[%a]@\n"
Typ.Procname.pp procname (List.length params) (Pp.seq Exp.pp)
(List.map ~f:fst params) (List.length params_stmt)
(Pp.seq (Pp.to_string ~f:Clang_ast_j.string_of_stmt))
params_stmt
in
let act_params =
if is_cf_retain_release then (Exp.Const (Const.Cint IntLit.one), Typ.mk (Tint Typ.IBool))
@ -1050,16 +1058,20 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let context = trans_state_pri.context in
let procname = Procdesc.get_proc_name context.procdesc in
let sil_loc = CLocation.get_sil_location si context in
(* first for method address, second for 'this' expression *)
assert (Int.equal (List.length result_trans_callee.exps) 2) ;
(* first for method address, second for 'this' expression and other parameters *)
assert (List.length result_trans_callee.exps >= 1) ;
let sil_method, _ = List.hd_exn result_trans_callee.exps in
let callee_pname =
match sil_method with Exp.Const Const.Cfun pn -> pn | _ -> assert false
(* method pointer not implemented, this shouldn't happen *)
match sil_method with
| Exp.Const Const.Cfun pn
-> pn
| _
-> (* method pointer not implemented, this shouldn't happen but it does (t21762295) *)
CFrontend_config.incorrect_assumption "Could not resolve CXX method call %a" Exp.pp
sil_method
in
(* As we may have nodes coming from different parameters we need to *)
(* call instruction for each parameter and collect the results *)
(* afterwards. The 'instructions' function does not do that *)
(* As we may have nodes coming from different parameters we need to call instruction for each
parameter and collect the results afterwards. The 'instructions' function does not do that *)
let result_trans_subexprs =
let trans_state_param = {trans_state_pri with succ_nodes= []; var_exp_typ= None} in
let instruction' = exec_with_self_exception (exec_with_glvalue_as_reference instruction) in
@ -1175,7 +1187,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
CMethod_trans.get_class_name_method_call_from_receiver_kind context obj_c_message_expr_info
act_params
in
raise (Self.SelfClassException class_name) (* alloc or new *)
(* alloc or new *)
(* FIXME(t21762295): we do not expect this to propagate to the top but it does *)
raise (Self.SelfClassException class_name)
else if String.equal selector CFrontend_config.alloc
|| String.equal selector CFrontend_config.new_str
then
@ -1489,8 +1503,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let root_nodes' = if root_nodes <> [] then root_nodes else op_res_trans.root_nodes in
{op_res_trans with root_nodes= root_nodes'}
| _
-> L.(debug Capture Medium) "BinaryConditionalOperator not translated@." ;
assert false
-> CFrontend_config.unimplemented "BinaryConditionalOperator not translated"
(* Translate a condition for if/loops statement. It shorts-circuit and/or. *)
(* The invariant is that the translation of a condition always contains (at least) *)
@ -1810,7 +1823,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
(* succ_nodes will remove the temps *)
{empty_res_trans with root_nodes= top_nodes; leaf_nodes= succ_nodes}
| _
-> assert false
-> (* TODO(t21762295) this raises sometimes *)
CFrontend_config.incorrect_assumption
"Unexpected Switch Statement sub-expression list: [%a]"
(Pp.semicolon_seq (Pp.to_string ~f:Clang_ast_j.string_of_stmt))
switch_stmt_list
and stmtExpr_trans trans_state stmt_list =
let stmt =
@ -2058,7 +2075,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| Tint _ | Tfloat _ | Tptr _
-> initListExpr_builtin_trans trans_state_pri init_stmt_info stmts var_exp var_typ
| _
-> assert false
-> CFrontend_config.unimplemented "InitListExp for var %a of type %a" Exp.pp var_exp
(Typ.pp Pp.text) var_typ
in
let nname = "InitListExp" in
let res_trans =
@ -2185,8 +2203,10 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| (RecordDecl _) :: var_decls'
-> (* Record declaration is done in the beginning when procdesc is defined.*)
collect_all_decl trans_state var_decls' next_nodes stmt_info
| _
-> assert false
| decl :: _
-> CFrontend_config.incorrect_assumption "unexpected decl type %s in collect_all_decl: %a"
(Clang_ast_proj.get_decl_kind_string decl) (Pp.to_string ~f:Clang_ast_j.string_of_decl)
decl
(* stmt_list is ignored because it contains the same instructions as *)
(* the init expression. We use the latter info. *)
@ -2196,15 +2216,19 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let open Clang_ast_t in
match decl_list with
| (VarDecl _) :: _
-> (* Case for simple variable declarations*)
collect_all_decl trans_state decl_list succ_nodes stmt_info
| (CXXRecordDecl _) :: _ (*C++/C record decl treated in the same way *) | (RecordDecl _) :: _
(* Case for simple variable declarations*)
| (CXXRecordDecl _) :: _
(*C++/C record decl treated in the same way *)
| (RecordDecl _) :: _
-> (* Case for struct *)
collect_all_decl trans_state decl_list succ_nodes stmt_info
| _
-> L.(debug Capture Medium)
"WARNING: In DeclStmt found an unknown declaration type. RETURNING empty list of declaration. NEED TO BE FIXED" ;
empty_res_trans
| (TypedefDecl _) :: _ | (UsingDirectiveDecl _) :: _
-> empty_res_trans
| decl :: _
-> CFrontend_config.unimplemented "In DeclStmt found an unknown declaration type %s"
(Clang_ast_j.string_of_decl decl)
| []
-> assert false
in
{res_trans with leaf_nodes= []}
@ -2246,7 +2270,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
how x.f = a is actually implemented by the runtime.*)
and pseudoObjectExpr_trans trans_state stmt_list =
L.(debug Capture Verbose)
" priority node free = '%s'@\n@."
" priority node free = '%s'@\n@\n"
(string_of_bool (PriorityNode.is_priority_free trans_state)) ;
let rec do_semantic_elements el =
let open Clang_ast_t in
@ -2906,9 +2930,15 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| NullStmt _, FallThroughAttr _
-> no_op_trans trans_state.succ_nodes
| _
-> assert false (* More cases to come. With the assert false we can find them *) )
-> CFrontend_config.unimplemented
"attributedStmt [stmt] [attr] with:@\nstmt=%s@\nattr=%s@\n"
(Clang_ast_j.string_of_stmt stmt) (Clang_ast_j.string_of_attribute attr) )
| _
-> assert false
-> CFrontend_config.unimplemented "attributedStmt with:@\nstmts=[%a]@\nattrs=[%a]@\n"
(Pp.semicolon_seq (Pp.to_string ~f:Clang_ast_j.string_of_stmt))
stmts
(Pp.semicolon_seq (Pp.to_string ~f:Clang_ast_j.string_of_attribute))
attrs
and breakStmt_trans trans_state stmt_info =
match trans_state.continuation with
@ -2986,9 +3016,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| SwitchStmt (stmt_info, switch_stmt_list)
-> switchStmt_trans trans_state stmt_info switch_stmt_list
| CaseStmt _
-> L.(debug Capture Verbose)
"FATAL: Passing from CaseStmt outside of SwitchStmt, terminating.@\n" ;
assert false
-> (* where do we even get case stmts outside of the switch stmt? (t21762295) *)
CFrontend_config.incorrect_assumption "Case statement outside of switch statement: %a"
(Pp.to_string ~f:Clang_ast_j.string_of_stmt) instr
| StmtExpr (_, stmt_list, _)
-> stmtExpr_trans trans_state stmt_list
| ForStmt (stmt_info, [init; decl_stmt; cond; incr; body])
@ -3167,9 +3197,105 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| SubstNonTypeTemplateParmExpr _
| SubstNonTypeTemplateParmPackExpr _
| CXXDependentScopeMemberExpr _
-> raise (CTrans_utils.TemplatedCodeException instr)
| s
-> raise (CTrans_utils.UnsupportedStatementException s)
-> raise
(CFrontend_config.unimplemented "Translation of templated code is unsupported: %a"
(Pp.to_string ~f:Clang_ast_j.string_of_stmt) instr)
| ForStmt (_, _) | WhileStmt (_, _) | DoStmt (_, _) | ObjCForCollectionStmt (_, _)
-> assert false
| MSAsmStmt _
| CapturedStmt _
| CoreturnStmt _
| CoroutineBodyStmt _
| AddrLabelExpr _
| ArrayTypeTraitExpr _
| AsTypeExpr _
| AtomicExpr _
| CXXFoldExpr _
| CXXInheritedCtorInitExpr _
| CXXUnresolvedConstructExpr _
| CXXUuidofExpr _
| CUDAKernelCallExpr _
| ChooseExpr _
| ConvertVectorExpr _
| CoawaitExpr _
| CoyieldExpr _
| DependentCoawaitExpr _
| DependentScopeDeclRefExpr _
| DesignatedInitExpr _
| DesignatedInitUpdateExpr _
| ExpressionTraitExpr _
| FunctionParmPackExpr _
| ImaginaryLiteral _
| MSPropertyRefExpr _
| MSPropertySubscriptExpr _
| NoInitExpr _
| OMPArraySectionExpr _
| ObjCAvailabilityCheckExpr _
| ObjCIsaExpr _
| ObjCSubscriptRefExpr _
| UnresolvedLookupExpr _
| UnresolvedMemberExpr _
| PackExpansionExpr _
| ParenListExpr _
| TypoExpr _
| IndirectGotoStmt _
| MSDependentExistsStmt _
| OMPAtomicDirective _
| OMPBarrierDirective _
| OMPCancelDirective _
| OMPCancellationPointDirective _
| OMPCriticalDirective _
| OMPFlushDirective _
| OMPDistributeDirective _
| OMPDistributeParallelForDirective _
| OMPDistributeParallelForSimdDirective _
| OMPDistributeSimdDirective _
| OMPForDirective _
| OMPForSimdDirective _
| OMPParallelForDirective _
| OMPParallelForSimdDirective _
| OMPSimdDirective _
| OMPTargetParallelForSimdDirective _
| OMPTargetSimdDirective _
| OMPTargetTeamsDistributeDirective _
| OMPTargetTeamsDistributeParallelForDirective _
| OMPTargetTeamsDistributeParallelForSimdDirective _
| OMPTargetTeamsDistributeSimdDirective _
| OMPTaskLoopDirective _
| OMPTaskLoopSimdDirective _
| OMPTeamsDistributeDirective _
| OMPTeamsDistributeParallelForDirective _
| OMPTeamsDistributeParallelForSimdDirective _
| OMPTeamsDistributeSimdDirective _
| OMPMasterDirective _
| OMPOrderedDirective _
| OMPParallelDirective _
| OMPParallelSectionsDirective _
| OMPSectionDirective _
| OMPSectionsDirective _
| OMPSingleDirective _
| OMPTargetDataDirective _
| OMPTargetDirective _
| OMPTargetEnterDataDirective _
| OMPTargetExitDataDirective _
| OMPTargetParallelDirective _
| OMPTargetParallelForDirective _
| OMPTargetTeamsDirective _
| OMPTargetUpdateDirective _
| OMPTaskDirective _
| OMPTaskgroupDirective _
| OMPTaskwaitDirective _
| OMPTaskyieldDirective _
| OMPTeamsDirective _
| SEHExceptStmt _
| SEHFinallyStmt _
| SEHLeaveStmt _
| SEHTryStmt _
| DefaultStmt _
-> raise
(CFrontend_config.unimplemented "Statement translation for kind %s: %a"
(Clang_ast_proj.get_stmt_kind_string instr)
(Pp.to_string ~f:Clang_ast_j.string_of_stmt) instr)
(* Function similar to instruction function, but it takes C++ constructor initializer as
an input parameter. *)

@ -14,10 +14,6 @@ module Hashtbl = Caml.Hashtbl
module L = Logging
exception TemplatedCodeException of Clang_ast_t.stmt
exception UnsupportedStatementException of Clang_ast_t.stmt
(* Extract the element of a singleton list. If the list is not a singleton *)
(* It stops the computation giving a warning. We use this because we *)
(* assume in many places that a list is just a singleton. We use the *)
@ -653,8 +649,7 @@ let rec get_type_from_exp_stmt stmt =
| DeclRefExpr (_, _, _, info)
-> do_decl_ref_exp info
| _
-> L.internal_error "Failing with: %s@\n%!" (Clang_ast_j.string_of_stmt stmt) ;
assert false
-> L.die InternalError "get_type_from_expr_stmt failure: %s" (Clang_ast_j.string_of_stmt stmt)
module Self = struct
exception SelfClassException of Typ.Name.t
@ -793,7 +788,7 @@ let is_dispatch_function stmt_list =
try
let arg_stmt = List.nth_exn arg_stmts block_arg_pos in
if is_block_stmt arg_stmt then Some block_arg_pos else None
with Failure _ -> None )
with Invalid_argument _ -> None )
| _
-> None )
| _ ->

@ -36,10 +36,6 @@ type trans_result =
; initd_exps: Exp.t list
; is_cpp_call_virtual: bool }
exception TemplatedCodeException of Clang_ast_t.stmt
exception UnsupportedStatementException of Clang_ast_t.stmt
val empty_res_trans : trans_result
val undefined_expression : unit -> Exp.t

@ -118,11 +118,9 @@ let mark proc_name ann asig (b, bs) =
in
let params' =
let fail () =
L.internal_error
"INTERNAL ERROR: annotation for procedure %s has wrong number of arguments@."
(Typ.Procname.to_unique_id proc_name) ;
L.internal_error " ANNOTATED SIGNATURE: %a@." (pp proc_name) asig ;
assert false
L.die InternalError
"Annotation for procedure %s has wrong number of arguments.@\n Annotated signature: %a"
(Typ.Procname.to_unique_id proc_name) (pp proc_name) asig
in
let rec combine l1 l2 =
match (l1, l2) with

@ -44,9 +44,7 @@ module Inference = struct
if String.is_empty s_old then 0
else
try int_of_string s_old
with Failure _ ->
L.internal_error "int_of_string %s@." s_old ;
assert false
with Failure _ -> L.die InternalError "int_of_string %s" s_old
in
string_of_int (n + 1)

@ -150,8 +150,7 @@ let rec inhabit_typ tenv typ cfg env =
| Typ.Tfloat _
-> (Exp.Const (Const.Cfloat 0.0), env)
| _
-> L.internal_error "Couldn't inhabit typ: %a@." (Typ.pp Pp.text) typ ;
assert false
-> L.die InternalError "Couldn't inhabit typ: %a" (Typ.pp Pp.text) typ
in
let inhabited_exp, env' =
inhabit_internal typ {env with cur_inhabiting= TypSet.add typ env.cur_inhabiting}

Loading…
Cancel
Save