[nullsafe][logs] More logs

Summary:
1. Log cases when we fall back to default while typechecking (we aim to
gradually reduce their usage)
2. Log high level operations when checking field assignment

Reviewed By: ngorogiannis

Differential Revision: D20334923

fbshipit-source-id: 80c45b29e
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent 66c5f1bbe4
commit 83e72b2cbc

@ -9,6 +9,8 @@ open! IStd
(** Module for the checks called by Eradicate. *) (** Module for the checks called by Eradicate. *)
module L = Logging
let report_error tenv = TypeErr.report_error (EradicateCheckers.report_error tenv) let report_error tenv = TypeErr.report_error (EradicateCheckers.report_error tenv)
let explain_expr tenv node e = let explain_expr tenv node e =
@ -117,56 +119,59 @@ let check_condition_for_redundancy tenv ~is_always_true find_canonical_duplicate
(** Check an assignment to a field. *) (** Check an assignment to a field. *)
let check_field_assignment ~nullsafe_mode tenv find_canonical_duplicate curr_pdesc node instr_ref let check_field_assignment ~nullsafe_mode tenv find_canonical_duplicate curr_pdesc node instr_ref
typestate exp_lhs exp_rhs typ loc fname annotated_field_opt typecheck_expr : unit = typestate exp_lhs exp_rhs typ loc fname annotated_field_opt typecheck_expr : unit =
let curr_pname = Procdesc.get_proc_name curr_pdesc in L.d_with_indent ~name:"check_field_assignment" (fun () ->
let curr_pattrs = Procdesc.get_attributes curr_pdesc in let curr_pname = Procdesc.get_proc_name curr_pdesc in
let t_lhs, inferred_nullability_lhs = let curr_pattrs = Procdesc.get_attributes curr_pdesc in
typecheck_expr node instr_ref curr_pdesc typestate exp_lhs let t_lhs, inferred_nullability_lhs =
(* TODO(T54687014) optimistic default might be an unsoundness issue - investigate *) L.d_strln "Typechecking lhs" ;
(typ, InferredNullability.create TypeOrigin.OptimisticFallback) typecheck_expr node instr_ref curr_pdesc typestate exp_lhs
loc (* TODO(T54687014) optimistic default might be an unsoundness issue - investigate *)
in (typ, InferredNullability.create TypeOrigin.OptimisticFallback)
let _, inferred_nullability_rhs = loc
typecheck_expr node instr_ref curr_pdesc typestate exp_rhs in
(* TODO(T54687014) optimistic default might be an unsoundness issue - investigate *) let _, inferred_nullability_rhs =
(typ, InferredNullability.create TypeOrigin.OptimisticFallback) L.d_strln "Typechecking rhs" ;
loc typecheck_expr node instr_ref curr_pdesc typestate exp_rhs
in (* TODO(T54687014) optimistic default might be an unsoundness issue - investigate *)
let field_is_injector_readwrite () = (typ, InferredNullability.create TypeOrigin.OptimisticFallback)
match annotated_field_opt with loc
| Some AnnotatedField.{annotation_deprecated} ->
Annotations.ia_is_field_injector_readwrite annotation_deprecated
| _ ->
false
in
let field_is_in_cleanup_context () =
let AnnotatedSignature.{ret_annotation_deprecated} =
(* TODO(T62825735): support trusted callees for fields *)
(Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv curr_pattrs).ret
in
Annotations.ia_is_cleanup ret_annotation_deprecated
in
let assignment_check_result =
AssignmentRule.check ~nullsafe_mode
~lhs:(InferredNullability.get_nullability inferred_nullability_lhs)
~rhs:(InferredNullability.get_nullability inferred_nullability_rhs)
in
Result.iter_error assignment_check_result ~f:(fun assignment_violation ->
let should_report =
(not (AndroidFramework.is_destroy_method curr_pname))
&& PatternMatch.type_is_class t_lhs
&& (not (Fieldname.is_java_outer_instance fname))
&& (not (field_is_injector_readwrite ()))
&& not (field_is_in_cleanup_context ())
in in
if should_report then let field_is_injector_readwrite () =
let rhs_origin = InferredNullability.get_origin inferred_nullability_rhs in match annotated_field_opt with
report_error tenv find_canonical_duplicate | Some AnnotatedField.{annotation_deprecated} ->
(TypeErr.Bad_assignment Annotations.ia_is_field_injector_readwrite annotation_deprecated
{ assignment_violation | _ ->
; assignment_location= loc false
; rhs_origin in
; assignment_type= AssignmentRule.AssigningToField fname }) let field_is_in_cleanup_context () =
(Some instr_ref) loc curr_pdesc ) let AnnotatedSignature.{ret_annotation_deprecated} =
(* TODO(T62825735): support trusted callees for fields *)
(Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv curr_pattrs).ret
in
Annotations.ia_is_cleanup ret_annotation_deprecated
in
let assignment_check_result =
AssignmentRule.check ~nullsafe_mode
~lhs:(InferredNullability.get_nullability inferred_nullability_lhs)
~rhs:(InferredNullability.get_nullability inferred_nullability_rhs)
in
Result.iter_error assignment_check_result ~f:(fun assignment_violation ->
let should_report =
(not (AndroidFramework.is_destroy_method curr_pname))
&& PatternMatch.type_is_class t_lhs
&& (not (Fieldname.is_java_outer_instance fname))
&& (not (field_is_injector_readwrite ()))
&& not (field_is_in_cleanup_context ())
in
if should_report then
let rhs_origin = InferredNullability.get_origin inferred_nullability_rhs in
report_error tenv find_canonical_duplicate
(TypeErr.Bad_assignment
{ assignment_violation
; assignment_location= loc
; rhs_origin
; assignment_type= AssignmentRule.AssigningToField fname })
(Some instr_ref) loc curr_pdesc ) )
(* Check if the field declared as not nullable (implicitly or explicitly). If the field is (* Check if the field declared as not nullable (implicitly or explicitly). If the field is

@ -131,9 +131,15 @@ let rec typecheck_expr ~nullsafe_mode find_canonical_duplicate visited checks te
(* We already considered case of null literal above, so this is a non-null const. *) (* We already considered case of null literal above, so this is a non-null const. *)
(typ, InferredNullability.create (TypeOrigin.NonnullConst loc)) (typ, InferredNullability.create (TypeOrigin.NonnullConst loc))
| Exp.Lvar pvar -> | Exp.Lvar pvar ->
Option.value (TypeState.lookup_pvar pvar typestate) ~default:tr_default TypeState.lookup_pvar pvar typestate
|> IOption.if_none_eval ~f:(fun () ->
L.d_strln "WARNING: could not lookup Pvar in typestate: fallback to default" ;
tr_default )
| Exp.Var id -> | Exp.Var id ->
Option.value (TypeState.lookup_id id typestate) ~default:tr_default TypeState.lookup_id id typestate
|> IOption.if_none_eval ~f:(fun () ->
L.d_strln "WARNING: could not lookup Id in typestate: fallback to default" ;
tr_default )
| Exp.Exn e1 -> | Exp.Exn e1 ->
typecheck_expr ~nullsafe_mode find_canonical_duplicate visited checks tenv node instr_ref typecheck_expr ~nullsafe_mode find_canonical_duplicate visited checks tenv node instr_ref
curr_pdesc typestate e1 tr_default loc curr_pdesc typestate e1 tr_default loc
@ -154,6 +160,7 @@ let rec typecheck_expr ~nullsafe_mode find_canonical_duplicate visited checks te
, InferredNullability.create , InferredNullability.create
(TypeOrigin.Field {object_origin; field_name; field_type; access_loc= loc}) ) (TypeOrigin.Field {object_origin; field_name; field_type; access_loc= loc}) )
| None -> | None ->
L.d_strln "WARNING: could not lookup field annotation: fallback to default" ;
tr_default tr_default
in in
if checks.eradicate then if checks.eradicate then
@ -177,6 +184,7 @@ let rec typecheck_expr ~nullsafe_mode find_canonical_duplicate visited checks te
let typ, _ = tr_default in let typ, _ = tr_default in
(typ, InferredNullability.create TypeOrigin.ArrayAccess) (typ, InferredNullability.create TypeOrigin.ArrayAccess)
| _ -> | _ ->
L.d_strln "WARNING: unknown expression: fallback to default" ;
tr_default ) tr_default )

Loading…
Cancel
Save