[erl-frontend] Support xor expressions

Summary: Add support for the xor operator by reducing `(X xor Y)` to `(X and not Y) or (not X and Y)`. Alternatively, `(X != Y)` could have been used but that might not be safe since SIL models Booleans with integers.

Reviewed By: skcho

Differential Revision: D29816793

fbshipit-source-id: 2496b718b
master
Akos Hajdu 3 years ago committed by Facebook GitHub Bot
parent 888521a2ab
commit 8f797bab84

@ -418,6 +418,15 @@ and translate_expression env {Ast.line; simple_expression} =
make_simple_eager Mod (* TODO: check semantics of Rem vs Mod *) make_simple_eager Mod (* TODO: check semantics of Rem vs Mod *)
| Sub -> | Sub ->
make_simple_eager (MinusA None) make_simple_eager (MinusA None)
| Xor ->
let expr =
Exp.BinOp
( LOr
, Exp.BinOp (LAnd, Var id1, Exp.UnOp (LNot, Var id2, None))
, Exp.BinOp (LAnd, Exp.UnOp (LNot, Var id1, None), Var id2) )
in
let op_block = Block.make_load env ret_var expr any in
Block.all env [block1; block2; op_block]
| todo -> | todo ->
L.debug Capture Verbose L.debug Capture Verbose
"@[todo ErlangTranslator.translate_expression(BinaryOperator) %s@." "@[todo ErlangTranslator.translate_expression(BinaryOperator) %s@."

@ -36,6 +36,8 @@ codetoanalyze/erlang/features/src/logic.erl, test_andalso10_Bad/0, 1, NO_TRUE_BR
codetoanalyze/erlang/features/src/logic.erl, test_or00_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here] codetoanalyze/erlang/features/src/logic.erl, test_or00_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here]
codetoanalyze/erlang/features/src/logic.erl, test_orelse00_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here] codetoanalyze/erlang/features/src/logic.erl, test_orelse00_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here]
codetoanalyze/erlang/features/src/logic.erl, test_unot_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here] codetoanalyze/erlang/features/src/logic.erl, test_unot_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here]
codetoanalyze/erlang/features/src/logic.erl, test_xor00_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here]
codetoanalyze/erlang/features/src/logic.erl, test_xor11_Bad/0, 1, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here]
codetoanalyze/erlang/features/src/short_circuit.erl, accepts_one/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here] codetoanalyze/erlang/features/src/short_circuit.erl, accepts_one/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here]
codetoanalyze/erlang/features/src/short_circuit.erl, test_and_Bad/0, -7, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_one/1`,no matching function clause here] codetoanalyze/erlang/features/src/short_circuit.erl, test_and_Bad/0, -7, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_one/1`,no matching function clause here]
codetoanalyze/erlang/features/src/short_circuit.erl, test_andalso_Bad/0, -15, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_one/1`,no matching function clause here] codetoanalyze/erlang/features/src/short_circuit.erl, test_andalso_Bad/0, -15, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `accepts_one/1`,no matching function clause here]

@ -27,7 +27,11 @@
test_orelse10_Ok/0, test_orelse10_Ok/0,
test_orelse11_Ok/0, test_orelse11_Ok/0,
test_unot_Ok/0, test_unot_Ok/0,
test_unot_Bad/0 test_unot_Bad/0,
test_xor00_Bad/0,
test_xor01_Ok/0,
test_xor10_Ok/0,
test_xor11_Bad/0
]). ]).
test_and00_Bad() -> test_and00_Bad() ->
@ -119,3 +123,23 @@ test_unot_Bad() ->
if if
not ?T -> ok not ?T -> ok
end. end.
test_xor00_Bad() ->
if
?F xor ?F -> ok
end.
test_xor01_Ok() ->
if
?F xor ?T -> ok
end.
test_xor10_Ok() ->
if
?T xor ?F -> ok
end.
test_xor11_Bad() ->
if
?T xor ?T -> ok
end.

Loading…
Cancel
Save