[erl-frontend] Split generic warning message to specific ones

Summary: Previously we just reported NONEXHAUSTIVE_PATTERN_MATCH, which was (1) not correct because not only patterns can cause nonexhaustive behavior, but also guards, and (2) the Erlang runtime reports errors more precisely, indicating whether the nonexhaustive behavior occurs with `if`, `case`, functions or match expressions.

Reviewed By: rgrig

Differential Revision: D29681637

fbshipit-source-id: 74a25b371
master
Akos Hajdu 3 years ago committed by Facebook GitHub Bot
parent 02d413061a
commit c337b06258

@ -1,10 +0,0 @@
## Nonexhaustive pattern match in Erlang
Reports an error when a function clause is missing.
For example, if we call `tail([])` and the full definition of `tail` is
```erlang
tail([_|Xs]) -> Xs.
```
The error is also reported if the failing pattern match is in a `case` expression.

@ -0,0 +1,13 @@
## No matching case clause in Erlang
Reports an error when none of the clauses of a `case` match the expression. Corresponds to the `{case_clause,V}` error in the Erlang runtime.
For example, if we call `tail([])` and the full definition of `tail` is
```erlang
tail(X) ->
case X of
[_|T] -> T
end.
```
This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses.

@ -0,0 +1,10 @@
## No matching function clause in Erlang
Reports an error when none of the clauses of a function match the arguments of a call. Corresponds to the `function_clause` error in the Erlang runtime.
For example, if we call `tail([])` and the full definition of `tail` is
```erlang
tail([_|Xs]) -> Xs.
```
This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses.

@ -0,0 +1,5 @@
## No match of right hand side value in Erlang
Reports an error when the right hand side value of a `match` expression does not match the pattern on the left hand side. Corresponds to the `{badmatch,V}` error in the Erlang runtime.
For example, `[H|T] = []` gives the error because the left hand side pattern requires at least one element in the list on the right hand side.

@ -0,0 +1,12 @@
## No true branch when evaluating an if expression in Erlang
Reports an error when none of the branches of an `if` expression evaluate to true. Corresponds to the `if_clause` error in the Erlang runtime.
For example, if we call `sign(0)` and the full definition of `sign` is
```erlang
sign(X) ->
if
X > 0 -> positive;
X < 0 -> negative
end.
```

@ -550,7 +550,10 @@ OPTIONS
NIL_BLOCK_CALL (enabled by default),
NIL_INSERTION_INTO_COLLECTION (enabled by default),
NIL_MESSAGING_TO_NON_POD (enabled by default),
NONEXHAUSTIVE_PATTERN_MATCH (enabled by default),
NO_MATCHING_CASE_CLAUSE (enabled by default),
NO_MATCHING_FUNCTION_CLAUSE (enabled by default),
NO_MATCH_OF_RHS (enabled by default),
NO_TRUE_BRANCH_IN_IF (enabled by default),
NULLPTR_DEREFERENCE (enabled by default),
NULL_DEREFERENCE (enabled by default),
OPTIONAL_EMPTY_ACCESS (enabled by default),

@ -221,7 +221,10 @@ OPTIONS
NIL_BLOCK_CALL (enabled by default),
NIL_INSERTION_INTO_COLLECTION (enabled by default),
NIL_MESSAGING_TO_NON_POD (enabled by default),
NONEXHAUSTIVE_PATTERN_MATCH (enabled by default),
NO_MATCHING_CASE_CLAUSE (enabled by default),
NO_MATCHING_FUNCTION_CLAUSE (enabled by default),
NO_MATCH_OF_RHS (enabled by default),
NO_TRUE_BRANCH_IN_IF (enabled by default),
NULLPTR_DEREFERENCE (enabled by default),
NULL_DEREFERENCE (enabled by default),
OPTIONAL_EMPTY_ACCESS (enabled by default),

@ -550,7 +550,10 @@ OPTIONS
NIL_BLOCK_CALL (enabled by default),
NIL_INSERTION_INTO_COLLECTION (enabled by default),
NIL_MESSAGING_TO_NON_POD (enabled by default),
NONEXHAUSTIVE_PATTERN_MATCH (enabled by default),
NO_MATCHING_CASE_CLAUSE (enabled by default),
NO_MATCHING_FUNCTION_CLAUSE (enabled by default),
NO_MATCH_OF_RHS (enabled by default),
NO_TRUE_BRANCH_IN_IF (enabled by default),
NULLPTR_DEREFERENCE (enabled by default),
NULL_DEREFERENCE (enabled by default),
OPTIONAL_EMPTY_ACCESS (enabled by default),

@ -76,12 +76,18 @@ let __delete_array = create_procname "__delete_array"
let __delete_locked_attribute = create_procname "__delete_locked_attribute"
let __erlang_error_badmatch = create_procname "__erlang_error_badmatch"
let __erlang_error_case_clause = create_procname "__erlang_error_case_clause"
let __erlang_error_function_clause = create_procname "__erlang_error_function_clause"
let __erlang_error_if_clause = create_procname "__erlang_error_if_clause"
let __erlang_make_cons = create_procname "__erlang_make_cons"
let __erlang_make_nil = create_procname "__erlang_make_nil"
let __erlang_pattern_fail = create_procname "__erlang_pattern_fail"
let __exit = create_procname "_exit"
let __objc_bridge_transfer = create_procname "__objc_bridge_transfer"

@ -13,13 +13,18 @@ include BUILTINS.S with type t = Procname.t
val is_declared : Procname.t -> bool
val __erlang_error_badmatch : Procname.t
val __erlang_error_case_clause : Procname.t
val __erlang_error_function_clause : Procname.t
val __erlang_error_if_clause : Procname.t
val __erlang_make_cons : Procname.t
val __erlang_make_nil : Procname.t
val __erlang_pattern_fail : Procname.t
(** all patterns in a function failed to match *)
val __infer_initializer_list : Procname.t
val __infer_skip_function : Procname.t

@ -804,9 +804,24 @@ let nil_messaging_to_non_pod =
~user_documentation:[%blob "../../documentation/issues/NIL_MESSAGING_TO_NON_POD.md"]
let nonexhaustive_pattern_match =
register ~id:"NONEXHAUSTIVE_PATTERN_MATCH" Error Pulse
~user_documentation:[%blob "../../documentation/issues/NONEXHAUSTIVE_PATTERN_MATCH.md"]
let no_match_of_rhs =
register ~id:"NO_MATCH_OF_RHS" Error Pulse
~user_documentation:[%blob "../../documentation/issues/NO_MATCH_OF_RHS.md"]
let no_matching_case_clause =
register ~id:"NO_MATCHING_CASE_CLAUSE" Error Pulse
~user_documentation:[%blob "../../documentation/issues/NO_MATCHING_CASE_CLAUSE.md"]
let no_matching_function_clause =
register ~id:"NO_MATCHING_FUNCTION_CLAUSE" Error Pulse
~user_documentation:[%blob "../../documentation/issues/NO_MATCHING_FUNCTION_CLAUSE.md"]
let no_true_branch_in_if =
register ~id:"NO_TRUE_BRANCH_IN_IF" Error Pulse
~user_documentation:[%blob "../../documentation/issues/NO_TRUE_BRANCH_IN_IF.md"]
let null_dereference =

@ -282,7 +282,13 @@ val nil_insertion_into_collection : t
val nil_messaging_to_non_pod : t
val nonexhaustive_pattern_match : t
val no_match_of_rhs : t
val no_matching_case_clause : t
val no_matching_function_clause : t
val no_true_branch_in_if : t
val null_dereference : t

@ -158,11 +158,11 @@ module Node = struct
make env kind [prune]
let make_pattern_fail env =
let make_fail env fail_function =
let any = typ_of_name Any in
let crash_instruction =
let ret_var = Ident.create_fresh Ident.knormal (* not used: nothing returned *) in
let pattern_fail_fun = Exp.Const (Cfun BuiltinDecl.__erlang_pattern_fail) in
let pattern_fail_fun = Exp.Const (Cfun fail_function) in
Sil.Call ((ret_var, any), pattern_fail_fun, [], env.location, CallFlags.default)
in
make_throw env crash_instruction
@ -446,7 +446,7 @@ and translate_expression env {Ast.line; simple_expression} =
let id = Ident.create_fresh Ident.knormal in
let expr_block = translate_expression {env with result= Present (Exp.Var id)} expression in
let blocks = Block.any env (List.map ~f:(translate_case_clause env [id]) cases) in
let crash_node = Node.make_pattern_fail env in
let crash_node = Node.make_fail env BuiltinDecl.__erlang_error_case_clause in
blocks.exit_failure |~~> [crash_node] ;
let blocks = {blocks with exit_failure= crash_node} in
Block.all env [expr_block; blocks]
@ -463,7 +463,7 @@ and translate_expression env {Ast.line; simple_expression} =
Block.all env [head_block; tail_block; Block.make_instruction env [call_instruction]]
| If clauses ->
let blocks = Block.any env (List.map ~f:(translate_case_clause env []) clauses) in
let crash_node = Node.make_pattern_fail env in
let crash_node = Node.make_fail env BuiltinDecl.__erlang_error_if_clause in
blocks.exit_failure |~~> [crash_node] ;
let blocks = {blocks with exit_failure= crash_node} in
blocks
@ -484,7 +484,7 @@ and translate_expression env {Ast.line; simple_expression} =
| Match {pattern; body} ->
let body_block = translate_expression {env with result= Present (Exp.Var ret_var)} body in
let pattern_block = translate_pattern env ret_var pattern in
let crash_node = Node.make_pattern_fail env in
let crash_node = Node.make_fail env BuiltinDecl.__erlang_error_badmatch in
pattern_block.exit_failure |~~> [crash_node] ;
let pattern_block = {pattern_block with exit_failure= crash_node} in
Block.all env [body_block; pattern_block]
@ -604,8 +604,8 @@ let translate_one_function env cfg function_ clauses =
loads_node |~~> [start]
in
let () =
(* If all patterns fail, call BuiltinDecl.__erlang_pattern_fail *)
let crash_node = Node.make_pattern_fail env in
(* If all patterns fail, call special method *)
let crash_node = Node.make_fail env BuiltinDecl.__erlang_error_function_clause in
exit_failure |~~> [crash_node] ;
crash_node |~~> [Procdesc.get_exit_node procdesc]
in

@ -22,7 +22,11 @@ type access_to_invalid_address =
; must_be_valid_reason: Invalidation.must_be_valid_reason option }
[@@deriving compare, equal]
type nonexhaustive_pattern_match = {calling_context: calling_context; location: Location.t}
type erlang_error =
| Badmatch of {calling_context: calling_context; location: Location.t}
| Case_clause of {calling_context: calling_context; location: Location.t}
| Function_clause of {calling_context: calling_context; location: Location.t}
| If_clause of {calling_context: calling_context; location: Location.t}
[@@deriving compare, equal]
type read_uninitialized_value = {calling_context: calling_context; trace: Trace.t}
@ -30,14 +34,14 @@ type read_uninitialized_value = {calling_context: calling_context; trace: Trace.
let yojson_of_access_to_invalid_address = [%yojson_of: _]
let yojson_of_nonexhaustive_pattern_match = [%yojson_of: _]
let yojson_of_erlang_error = [%yojson_of: _]
let yojson_of_read_uninitialized_value = [%yojson_of: _]
type t =
| AccessToInvalidAddress of access_to_invalid_address
| MemoryLeak of {procname: Procname.t; allocation_trace: Trace.t; location: Location.t}
| NonexhaustivePatternMatch of nonexhaustive_pattern_match
| ErlangError of erlang_error
| ReadUninitializedValue of read_uninitialized_value
| StackVariableAddressEscape of {variable: Var.t; history: ValueHistory.t; location: Location.t}
[@@deriving equal]
@ -50,7 +54,10 @@ let get_location = function
| ReadUninitializedValue {calling_context= (_, location) :: _} ->
(* report at the call site that triggers the bug *) location
| MemoryLeak {location}
| NonexhaustivePatternMatch {location}
| ErlangError (Badmatch {location})
| ErlangError (Case_clause {location})
| ErlangError (Function_clause {location})
| ErlangError (If_clause {location})
| StackVariableAddressEscape {location} ->
location
@ -174,8 +181,14 @@ let get_message diagnostic =
"%s memory leak. Memory dynamically allocated at line %d %a is not freed after the last \
access at %a"
pulse_start_msg allocation_line pp_allocation_trace allocation_trace Location.pp location
| NonexhaustivePatternMatch {calling_context= _; location} ->
F.asprintf "%s nonexhaustive pattern match at %a" pulse_start_msg Location.pp location
| ErlangError (Badmatch {calling_context= _; location}) ->
F.asprintf "%s no match of RHS at %a" pulse_start_msg Location.pp location
| ErlangError (Case_clause {calling_context= _; location}) ->
F.asprintf "%s no matching case clause at %a" pulse_start_msg Location.pp location
| ErlangError (Function_clause {calling_context= _; location}) ->
F.asprintf "%s no matching function clause at %a" pulse_start_msg Location.pp location
| ErlangError (If_clause {calling_context= _; location}) ->
F.asprintf "%s no true branch in if expression at %a" pulse_start_msg Location.pp location
| ReadUninitializedValue {calling_context; trace} ->
let root_var =
PulseTrace.find_map trace ~f:(function VariableDeclared (pvar, _) -> Some pvar | _ -> None)
@ -309,9 +322,18 @@ let get_trace = function
~pp_immediate:(fun fmt -> F.fprintf fmt "allocated by `%a` here" Procname.pp procname)
allocation_trace
@@ [Errlog.make_trace_element 0 location "memory becomes unreachable here" []]
| NonexhaustivePatternMatch {calling_context; location} ->
| ErlangError (Badmatch {calling_context; location}) ->
get_trace_calling_context calling_context
@@ [Errlog.make_trace_element 0 location "no pattern match here" []]
@@ [Errlog.make_trace_element 0 location "no match of RHS here" []]
| ErlangError (Case_clause {calling_context; location}) ->
get_trace_calling_context calling_context
@@ [Errlog.make_trace_element 0 location "no matching case clause here" []]
| ErlangError (Function_clause {calling_context; location}) ->
get_trace_calling_context calling_context
@@ [Errlog.make_trace_element 0 location "no matching function clause here" []]
| ErlangError (If_clause {calling_context; location}) ->
get_trace_calling_context calling_context
@@ [Errlog.make_trace_element 0 location "no true branch in if expression here" []]
| ReadUninitializedValue {calling_context; trace} ->
get_trace_calling_context calling_context
@@ Trace.add_to_errlog ~nesting:0
@ -333,8 +355,14 @@ let get_issue_type = function
Invalidation.issue_type_of_cause invalidation must_be_valid_reason
| MemoryLeak _ ->
IssueType.pulse_memory_leak
| NonexhaustivePatternMatch _ ->
IssueType.nonexhaustive_pattern_match
| ErlangError (Badmatch _) ->
IssueType.no_match_of_rhs
| ErlangError (Case_clause _) ->
IssueType.no_matching_case_clause
| ErlangError (Function_clause _) ->
IssueType.no_matching_function_clause
| ErlangError (If_clause _) ->
IssueType.no_true_branch_in_if
| ReadUninitializedValue _ ->
IssueType.uninitialized_value_pulse
| StackVariableAddressEscape _ ->

@ -28,7 +28,11 @@ type access_to_invalid_address =
; must_be_valid_reason: Invalidation.must_be_valid_reason option }
[@@deriving compare, equal, yojson_of]
type nonexhaustive_pattern_match = {calling_context: calling_context; location: Location.t}
type erlang_error =
| Badmatch of {calling_context: calling_context; location: Location.t}
| Case_clause of {calling_context: calling_context; location: Location.t}
| Function_clause of {calling_context: calling_context; location: Location.t}
| If_clause of {calling_context: calling_context; location: Location.t}
[@@deriving compare, equal, yojson_of]
type read_uninitialized_value =
@ -44,7 +48,7 @@ type read_uninitialized_value =
type t =
| AccessToInvalidAddress of access_to_invalid_address
| MemoryLeak of {procname: Procname.t; allocation_trace: Trace.t; location: Location.t}
| NonexhaustivePatternMatch of nonexhaustive_pattern_match
| ErlangError of erlang_error
| ReadUninitializedValue of read_uninitialized_value
| StackVariableAddressEscape of {variable: Var.t; history: ValueHistory.t; location: Location.t}
[@@deriving equal]

@ -12,15 +12,15 @@ module Arithmetic = PulseArithmetic
type t =
| AccessToInvalidAddress of Diagnostic.access_to_invalid_address
| NonexhaustivePatternMatch of Diagnostic.nonexhaustive_pattern_match
| ErlangError of Diagnostic.erlang_error
| ReadUninitializedValue of Diagnostic.read_uninitialized_value
[@@deriving compare, equal, yojson_of]
let to_diagnostic = function
| AccessToInvalidAddress access_to_invalid_address ->
Diagnostic.AccessToInvalidAddress access_to_invalid_address
| NonexhaustivePatternMatch nonexhaustive_pattern_match ->
Diagnostic.NonexhaustivePatternMatch nonexhaustive_pattern_match
| ErlangError erlang_error ->
Diagnostic.ErlangError erlang_error
| ReadUninitializedValue read_uninitialized_value ->
Diagnostic.ReadUninitializedValue read_uninitialized_value
@ -28,9 +28,14 @@ let to_diagnostic = function
let add_call call_and_loc = function
| AccessToInvalidAddress access ->
AccessToInvalidAddress {access with calling_context= call_and_loc :: access.calling_context}
| NonexhaustivePatternMatch nonmatch ->
NonexhaustivePatternMatch
{nonmatch with calling_context= call_and_loc :: nonmatch.calling_context}
| ErlangError (Badmatch {calling_context; location}) ->
ErlangError (Badmatch {calling_context= call_and_loc :: calling_context; location})
| ErlangError (Case_clause {calling_context; location}) ->
ErlangError (Case_clause {calling_context= call_and_loc :: calling_context; location})
| ErlangError (Function_clause {calling_context; location}) ->
ErlangError (Function_clause {calling_context= call_and_loc :: calling_context; location})
| ErlangError (If_clause {calling_context; location}) ->
ErlangError (If_clause {calling_context= call_and_loc :: calling_context; location})
| ReadUninitializedValue read ->
ReadUninitializedValue {read with calling_context= call_and_loc :: read.calling_context}
@ -53,7 +58,7 @@ let should_report (astate : AbductiveDomain.summary) (diagnostic : Diagnostic.t)
`ReportNow
| AccessToInvalidAddress latent ->
if is_manifest astate then `ReportNow else `DelayReport (AccessToInvalidAddress latent)
| NonexhaustivePatternMatch latent ->
if is_manifest astate then `ReportNow else `DelayReport (NonexhaustivePatternMatch latent)
| ErlangError latent ->
if is_manifest astate then `ReportNow else `DelayReport (ErlangError latent)
| ReadUninitializedValue latent ->
if is_manifest astate then `ReportNow else `DelayReport (ReadUninitializedValue latent)

@ -15,7 +15,7 @@ module AbductiveDomain = PulseAbductiveDomain
type t =
| AccessToInvalidAddress of Diagnostic.access_to_invalid_address
| NonexhaustivePatternMatch of Diagnostic.nonexhaustive_pattern_match
| ErlangError of Diagnostic.erlang_error
| ReadUninitializedValue of Diagnostic.read_uninitialized_value
[@@deriving compare, equal, yojson_of]

@ -1507,11 +1507,32 @@ module Android = struct
end
module Erlang = struct
let pattern_fail : model =
let error_badmatch : model =
fun {location} astate ->
[ Error
(ReportableError {astate; diagnostic= ErlangError (Badmatch {calling_context= []; location})})
]
let error_case_clause : model =
fun {location} astate ->
[ Error
(ReportableError
{astate; diagnostic= ErlangError (Case_clause {calling_context= []; location})}) ]
let error_function_clause : model =
fun {location} astate ->
[ Error
(ReportableError
{astate; diagnostic= ErlangError (Function_clause {calling_context= []; location})}) ]
let error_if_clause : model =
fun {location} astate ->
[ Error
(ReportableError
{astate; diagnostic= NonexhaustivePatternMatch {calling_context= []; location}}) ]
{astate; diagnostic= ErlangError (If_clause {calling_context= []; location})}) ]
let make_nil : model =
@ -1627,7 +1648,11 @@ module ProcNameDispatcher = struct
; +BuiltinDecl.(match_builtin __erlang_make_cons)
<>$ capt_arg_payload $+ capt_arg_payload $--> Erlang.make_cons
; +BuiltinDecl.(match_builtin __erlang_make_nil) <>--> Erlang.make_nil
; +BuiltinDecl.(match_builtin __erlang_pattern_fail) <>--> Erlang.pattern_fail
; +BuiltinDecl.(match_builtin __erlang_error_badmatch) <>--> Erlang.error_badmatch
; +BuiltinDecl.(match_builtin __erlang_error_case_clause) <>--> Erlang.error_case_clause
; +BuiltinDecl.(match_builtin __erlang_error_function_clause)
<>--> Erlang.error_function_clause
; +BuiltinDecl.(match_builtin __erlang_error_if_clause) <>--> Erlang.error_if_clause
; +BuiltinDecl.(match_builtin __infer_initializer_list)
<>$ capt_arg_payload
$+...$--> Misc.id_first_arg ~desc:"infer_init_list"

@ -47,10 +47,7 @@ let is_nullsafe_error tenv diagnostic jn =
being equal to the value being dereferenced *)
let is_constant_deref_without_invalidation (diagnostic : Diagnostic.t) =
match diagnostic with
| MemoryLeak _
| NonexhaustivePatternMatch _
| ReadUninitializedValue _
| StackVariableAddressEscape _ ->
| MemoryLeak _ | ErlangError _ | ReadUninitializedValue _ | StackVariableAddressEscape _ ->
false
| AccessToInvalidAddress {invalidation; access_trace} -> (
match invalidation with

@ -1,15 +1,15 @@
codetoanalyze/erlang/features/src/arithmetic.erl, test_add1_Bad/0, -9, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_add2_Bad/0, -24, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_idiv1_Bad/0, -114, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul1_Bad/0, -69, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul2_Bad/0, -84, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul3_Bad/0, -99, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_multiple_Bad/0, -158, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_rem_Bad/0, -145, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_sub1_Bad/0, -39, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_sub2_Bad/0, -54, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus1_Bad/0, -170, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus2_Bad/0, -183, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, warn/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/features/src/block.erl, test_block_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no pattern match here]
codetoanalyze/erlang/features/src/block.erl, warn/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_add1_Bad/0, -9, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_add2_Bad/0, -24, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_idiv1_Bad/0, -114, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul1_Bad/0, -69, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul2_Bad/0, -84, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_mul3_Bad/0, -99, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_multiple_Bad/0, -158, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_rem_Bad/0, -145, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_sub1_Bad/0, -39, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_sub2_Bad/0, -54, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus1_Bad/0, -170, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus2_Bad/0, -183, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/arithmetic.erl, warn/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/features/src/block.erl, test_block_Bad/0, -15, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here]
codetoanalyze/erlang/features/src/block.erl, warn/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]

@ -1,30 +1,30 @@
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_simple/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_simple3_Bad/0, -14, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `case_simple/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_tail3_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail_with_case/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, tail_with_case/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, accepts_positive/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, accepts_positive2/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, test_accepts_positive2_Bad/0, -16, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive2/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, test_accepts_positive_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, assert_empty/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, assert_second_is_nil/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_empty2_Bad/0, -12, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_empty3_Bad/0, -14, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_secondnil3_Bad/0, -20, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_second_is_nil/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_tail3_Bad/0, -8, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function.erl, tail/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, accepts_positive/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, accepts_positive2/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, fp_accepts_all_tricky3/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, possible_exception/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_accepts_positive2_Bad/0, -23, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive2/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_accepts_positive_Bad/0, -19, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_possible_exception_Bad/0, -37, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `possible_exception/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/if_expression.erl, accepts_positive/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/if_expression.erl, test_accepts_positive_Bad/0, -13, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_simple/1, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_simple3_Bad/0, -14, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `case_simple/1`,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_tail3_Bad/0, -15, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `tail_with_case/1`,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_expression.erl, tail_with_case/1, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, accepts_positive/1, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, accepts_positive2/1, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, test_accepts_positive2_Bad/0, -16, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive2/1`,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/case_guards.erl, test_accepts_positive_Bad/0, -15, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no matching case clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, assert_empty/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, assert_second_is_nil/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_empty2_Bad/0, -12, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_empty3_Bad/0, -14, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_secondnil3_Bad/0, -20, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `assert_second_is_nil/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_tail3_Bad/0, -8, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function.erl, tail/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, accepts_positive/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, accepts_positive2/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, fp_accepts_all_tricky3/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, possible_exception/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_accepts_positive2_Bad/0, -23, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive2/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_accepts_positive_Bad/0, -19, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/function_guards.erl, test_possible_exception_Bad/0, -37, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `possible_exception/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/if_expression.erl, accepts_positive/1, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [*** LATENT ***,no true branch in if expression here]
codetoanalyze/erlang/nonmatch/src/if_expression.erl, test_accepts_positive_Bad/0, -13, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [calling context starts here,in call to `accepts_positive/1`,no true branch in if expression here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_b_Bad/0, 1, CONSTANT_ADDRESS_DEREFERENCE, no_bucket, WARNING, [in call to `two/0`,is the constant 2,assigned,returned,return from call to `two/0`,invalid access occurs here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_b_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_e_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_g_Bad/0, 7, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `only_accepts_one/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/match.erl, only_accepts_one/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/match.erl, tail/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_b_Bad/0, 1, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_e_Bad/0, -15, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/match.erl, match_test_g_Bad/0, 7, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `only_accepts_one/1`,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/match.erl, only_accepts_one/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/nonmatch/src/match.erl, tail/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]

@ -1,7 +1,7 @@
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_f_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_g_Ok/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_f_Bad/0, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [no matching case clause here]
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_g_Ok/0, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [no matching case clause here]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_a_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_c_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_d_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to call_sink_indirectly/1,call to call_sink/1,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_h_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to dirty_if_argument_nil/1,call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_j_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_j_Bad/0, 1, NO_MATCHING_CASE_CLAUSE, no_bucket, ERROR, [no matching case clause here]

Loading…
Cancel
Save