@ -100,7 +100,7 @@ let get_reporting_explanation_cpp = (IssueType.lock_consistency_violation, "")
(* * Explain why we are reporting this access *)
(* * Explain why we are reporting this access *)
let get_reporting_explanation ~ nullsafe report_kind tenv pname thread =
let get_reporting_explanation ~ nullsafe report_kind tenv pname thread =
if Procname . is_java pname then
if Procname . is_java pname | | Procname . is_csharp pname then
get_reporting_explanation_java ~ nullsafe report_kind tenv pname thread
get_reporting_explanation_java ~ nullsafe report_kind tenv pname thread
else get_reporting_explanation_cpp
else get_reporting_explanation_cpp
@ -357,6 +357,8 @@ end
let should_report_on_proc tenv procdesc =
let should_report_on_proc tenv procdesc =
let proc_name = Procdesc . get_proc_name procdesc in
let proc_name = Procdesc . get_proc_name procdesc in
match proc_name with
match proc_name with
| CSharp _ ->
not ( ProcAttributes . equal_access ( Procdesc . get_access procdesc ) Private )
| Java java_pname ->
| Java java_pname ->
(* return true if procedure is at an abstraction boundary or reporting has been explicitly
(* return true if procedure is at an abstraction boundary or reporting has been explicitly
requested via @ ThreadSafe in java * )
requested via @ ThreadSafe in java * )
@ -490,7 +492,7 @@ let report_unsafe_accesses ~issue_log file_tenv classname (aggregated_access_map
report_unannotated_interface_violation ~ acc reported_pname reported_access
report_unannotated_interface_violation ~ acc reported_pname reported_access
| InterfaceCall _ ->
| InterfaceCall _ ->
acc
acc
| ( Write _ | ContainerWrite _ ) when Procname . is_java pname ->
| ( Write _ | ContainerWrite _ ) when Procname . is_java pname || Procname . is_csharp pname ->
let conflict =
let conflict =
if ThreadsDomain . is_any threads then
if ThreadsDomain . is_any threads then
(* unprotected write in method that may run in parallel with itself. warn *)
(* unprotected write in method that may run in parallel with itself. warn *)
@ -520,7 +522,7 @@ let report_unsafe_accesses ~issue_log file_tenv classname (aggregated_access_map
let is_conflict { snapshot ; threads = other_threads } =
let is_conflict { snapshot ; threads = other_threads } =
AccessSnapshot . is_write snapshot
AccessSnapshot . is_write snapshot
&&
&&
if Procname . is_java pname then
if Procname . is_java pname | | Procname . is_csharp pname then
ThreadsDomain . is_any threads | | ThreadsDomain . is_any other_threads
ThreadsDomain . is_any threads | | ThreadsDomain . is_any other_threads
else not ( AccessSnapshot . is_unprotected snapshot )
else not ( AccessSnapshot . is_unprotected snapshot )
in
in
@ -532,7 +534,7 @@ let report_unsafe_accesses ~issue_log file_tenv classname (aggregated_access_map
let report_kind = ReadWriteRace conflict . snapshot in
let report_kind = ReadWriteRace conflict . snapshot in
report_thread_safety_violation ~ acc ~ make_description ~ report_kind ~ nullsafe
report_thread_safety_violation ~ acc ~ make_description ~ report_kind ~ nullsafe
reported_access )
reported_access )
| ( Read _ | ContainerRead _ ) when Procname . is_java pname ->
| ( Read _ | ContainerRead _ ) when Procname . is_java pname || Procname . is_csharp pname ->
(* protected read. report unprotected writes and opposite protected writes as conflicts *)
(* protected read. report unprotected writes and opposite protected writes as conflicts *)
let can_conflict ( snapshot1 : AccessSnapshot . t ) ( snapshot2 : AccessSnapshot . t ) =
let can_conflict ( snapshot1 : AccessSnapshot . t ) ( snapshot2 : AccessSnapshot . t ) =
if snapshot1 . elem . lock && snapshot2 . elem . lock then false
if snapshot1 . elem . lock && snapshot2 . elem . lock then false