@ -122,13 +122,11 @@ let rec format_string_type_names
let printf_args_name = " CHECKERS_PRINTF_ARGS "
let printf_args_name = " CHECKERS_PRINTF_ARGS "
let callback_printf_args
let check_printf_args_ok
( all_procs : Procname . t list )
( node : Cfg . Node . t )
( get_proc_desc : Procname . t -> Cfg . Procdesc . t option )
( instr : Sil . instr )
( idenv : Idenv . t )
( tenv : Sil . tenv )
( proc_name : Procname . t )
( proc_name : Procname . t )
( proc_desc : Cfg . Procdesc . t ) : unit =
( proc_desc : Cfg . Procdesc . t ) : unit =
(* Check if format string lines up with arguments *)
(* Check if format string lines up with arguments *)
let rec check_type_names instr_loc n_arg instr_proc_name fmt_type_names arg_type_names =
let rec check_type_names instr_loc n_arg instr_proc_name fmt_type_names arg_type_names =
@ -184,44 +182,49 @@ let callback_printf_args
| Sil . Const c -> PatternMatch . java_get_const_type_name c
| Sil . Const c -> PatternMatch . java_get_const_type_name c
| _ -> raise ( Failure " Could not resolve fixed type name " ) in
| _ -> raise ( Failure " Could not resolve fixed type name " ) in
let do_instr
match instr with
( node : Cfg . Node . t )
| Sil . Call ( _ , Sil . Const ( Sil . Cfun pn ) , args , cl , _ ) -> (
( instr : Sil . instr ) : unit =
match printf_like_function pn with
match instr with
| Some printf -> (
| Sil . Call ( _ , Sil . Const ( Sil . Cfun pn ) , args , cl , _ ) -> (
try
match printf_like_function pn with
let fmt , fixed_nvars , array_nvar = format_arguments printf args in
| Some printf -> (
let instrs = Cfg . Node . get_instrs node in
try
let fixed_nvar_type_names = IList . map ( fixed_nvar_type_name instrs ) fixed_nvars in
let fmt , fixed_nvars , array_nvar = format_arguments printf args in
let vararg_ivar_type_names = match array_nvar with
let instrs = Cfg . Node . get_instrs node in
| Some nvar -> (
let fixed_nvar_type_names = IList . map ( fixed_nvar_type_name instrs ) fixed_nvars in
let ivar = array_ivar instrs nvar in
let vararg_ivar_type_names = match array_nvar with
PatternMatch . get_vararg_type_names node ivar )
| Some nvar -> (
| None -> [] in
let ivar = array_ivar instrs nvar in
match fmt with
PatternMatch . get_vararg_type_names node ivar )
| Some fmt ->
| None -> [] in
check_type_names
match fmt with
cl
| Some fmt ->
( printf . format_pos + 1 )
check_type_names
pn
cl
( format_string_type_names fmt 0 )
( printf . format_pos + 1 )
( fixed_nvar_type_names @ vararg_ivar_type_names )
pn
| None ->
( format_string_type_names fmt 0 )
Checkers . ST . report_error
( fixed_nvar_type_names @ vararg_ivar_type_names )
proc_name
| None ->
proc_desc
Checkers . ST . report_error
printf_args_name
proc_name
cl
proc_desc
" Format string must be string literal "
printf_args_name
with e ->
cl
L . stderr
" Format string must be string literal "
" %s Exception when analyzing %s: %s@. "
with e ->
printf_args_name
L . stderr
( Procname . to_string proc_name )
" %s Exception when analyzing %s: %s@. "
( Printexc . to_string e ) )
printf_args_name
| None -> () )
( Procname . to_string proc_name )
| _ -> ()
( Printexc . to_string e ) )
| None -> () )
let callback_printf_args
| _ -> () in
( all_procs : Procname . t list )
( get_proc_desc : Procname . t -> Cfg . Procdesc . t option )
Cfg . Procdesc . iter_instrs do_instr proc_desc
( idenv : Idenv . t )
( tenv : Sil . tenv )
( proc_name : Procname . t )
( proc_desc : Cfg . Procdesc . t ) : unit =
Cfg . Procdesc . iter_instrs ( fun n i -> check_printf_args_ok n i proc_name proc_desc ) proc_desc