Skip to content

Commit

Permalink
[clang] Force evaluation order of the comma operator
Browse files Browse the repository at this point in the history
Summary:
When the comma operator is used, e.g. `e1,e2`, `e1` should be evaluated first.  This diff forces the
sequential order in the translation.

Reviewed By: dulmarod

Differential Revision: D55698280

fbshipit-source-id: 31e4e6db5effd19d6aca4463945b2befa3676f04
  • Loading branch information
skcho authored and facebook-github-bot committed Apr 9, 2024
1 parent c981aad commit 645829c
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 22 deletions.
14 changes: 14 additions & 0 deletions infer/src/clang/cTrans.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,20 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
[res_trans_e1.control; res_trans_e2.control; {empty_control with instrs}]
|> PriorityNode.compute_controls_to_parent trans_state_pri sil_loc node_name stmt_info
|> mk_trans_result res_trans_e1.return
| [s1; s2], _, `Comma ->
let ({control= {instrs}} as res_trans) =
CTrans_utils.PriorityNode.force_sequential sil_loc node_name trans_state stmt_info
~mk_first_opt:(fun trans_state _ -> Some (instruction trans_state s1))
~mk_second:(fun trans_state _ -> instruction trans_state s2)
~mk_return:(fun ~fst:_ ~snd -> snd.return)
in
(* HACK: With the empty instruction, the control is not correctly connected to the parent in
some cases, e.g. the comma binary operator is used on the top-level. See
[CTrans_utils.PriorityNode.compute_controls_to_parent]; the condition [create_node] is
true only when the instruction is non-empty. *)
if List.is_empty instrs then
{res_trans with control= {res_trans.control with instrs= [Metadata Skip]}}
else res_trans
| [s1; s2], _, _ ->
let {control= control1; return= (exp1, typ1) as exp_typ1} = instruction trans_state' s1 in
let {control= control2; return= exp_typ2} =
Expand Down
80 changes: 58 additions & 22 deletions infer/tests/codetoanalyze/c/frontend/comma/comma.c.dot
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ digraph cfg {
"comma_1.bafaed8336991f5a_1" [label="1: Start comma_1\nFormals: \nLocals: d:int b:int a:int \n " color=yellow style=filled]


"comma_1.bafaed8336991f5a_1" -> "comma_1.bafaed8336991f5a_7" ;
"comma_1.bafaed8336991f5a_1" -> "comma_1.bafaed8336991f5a_9" ;
"comma_1.bafaed8336991f5a_2" [label="2: Exit comma_1 \n " color=yellow style=filled]


Expand All @@ -15,22 +15,30 @@ digraph cfg {


"comma_1.bafaed8336991f5a_4" -> "comma_1.bafaed8336991f5a_2" ;
"comma_1.bafaed8336991f5a_5" [label="5: DeclStmt \n VARIABLE_DECLARED(d:int); [line 10, column 3]\n n$1=*&a:int [line 10, column 16]\n *&a:int=(n$1 * 2) [line 10, column 12]\n n$2=*&a:int [line 10, column 12]\n n$3=*&a:int [line 10, column 31]\n *&a:int=(n$3 + 1) [line 10, column 31]\n *&b:int=(7 * n$3) [line 10, column 23]\n n$4=*&b:int [line 10, column 23]\n *&d:int=n$4 [line 10, column 3]\n " shape="box"]
"comma_1.bafaed8336991f5a_5" [label="5: BinaryOperatorStmt: Comma \n n$3=*&a:int [line 10, column 16]\n *&a:int=(n$3 * 2) [line 10, column 12]\n n$4=*&a:int [line 10, column 12]\n n$1=*&a:int [line 10, column 31]\n *&a:int=(n$1 + 1) [line 10, column 31]\n *&b:int=(7 * n$1) [line 10, column 23]\n n$2=*&b:int [line 10, column 23]\n " shape="box"]


"comma_1.bafaed8336991f5a_5" -> "comma_1.bafaed8336991f5a_3" ;
"comma_1.bafaed8336991f5a_6" [label="6: DeclStmt \n VARIABLE_DECLARED(b:int); [line 9, column 3]\n *&b:int=7 [line 9, column 3]\n " shape="box"]
"comma_1.bafaed8336991f5a_5" -> "comma_1.bafaed8336991f5a_7" ;
"comma_1.bafaed8336991f5a_6" [label="6: DeclStmt \n VARIABLE_DECLARED(d:int); [line 10, column 3]\n " shape="box"]


"comma_1.bafaed8336991f5a_6" -> "comma_1.bafaed8336991f5a_5" ;
"comma_1.bafaed8336991f5a_7" [label="7: DeclStmt \n VARIABLE_DECLARED(a:int); [line 9, column 3]\n *&a:int=9 [line 9, column 3]\n " shape="box"]
"comma_1.bafaed8336991f5a_7" [label="7: DeclStmt \n SKIP\n *&d:int=n$2 [line 10, column 3]\n " shape="box"]


"comma_1.bafaed8336991f5a_7" -> "comma_1.bafaed8336991f5a_6" ;
"comma_1.bafaed8336991f5a_7" -> "comma_1.bafaed8336991f5a_3" ;
"comma_1.bafaed8336991f5a_8" [label="8: DeclStmt \n VARIABLE_DECLARED(b:int); [line 9, column 3]\n *&b:int=7 [line 9, column 3]\n " shape="box"]


"comma_1.bafaed8336991f5a_8" -> "comma_1.bafaed8336991f5a_6" ;
"comma_1.bafaed8336991f5a_9" [label="9: DeclStmt \n VARIABLE_DECLARED(a:int); [line 9, column 3]\n *&a:int=9 [line 9, column 3]\n " shape="box"]


"comma_1.bafaed8336991f5a_9" -> "comma_1.bafaed8336991f5a_8" ;
"comma_2.aa5fd44d8dfe7804_1" [label="1: Start comma_2\nFormals: \nLocals: d:int b:int a:int \n " color=yellow style=filled]


"comma_2.aa5fd44d8dfe7804_1" -> "comma_2.aa5fd44d8dfe7804_7" ;
"comma_2.aa5fd44d8dfe7804_1" -> "comma_2.aa5fd44d8dfe7804_10" ;
"comma_2.aa5fd44d8dfe7804_2" [label="2: Exit comma_2 \n " color=yellow style=filled]


Expand All @@ -42,22 +50,34 @@ digraph cfg {


"comma_2.aa5fd44d8dfe7804_4" -> "comma_2.aa5fd44d8dfe7804_2" ;
"comma_2.aa5fd44d8dfe7804_5" [label="5: DeclStmt \n VARIABLE_DECLARED(d:int); [line 16, column 3]\n n$1=*&a:int [line 16, column 16]\n *&a:int=(n$1 * 2) [line 16, column 12]\n n$2=*&a:int [line 16, column 12]\n n$3=*&a:int [line 16, column 31]\n *&a:int=(n$3 + 1) [line 16, column 31]\n *&b:int=(7 * n$3) [line 16, column 23]\n n$4=*&b:int [line 16, column 23]\n n$5=*&a:int [line 16, column 36]\n n$6=*&b:int [line 16, column 40]\n *&d:int=((n$5 + n$6) + 9) [line 16, column 3]\n " shape="box"]
"comma_2.aa5fd44d8dfe7804_5" [label="5: BinaryOperatorStmt: Comma \n n$5=*&a:int [line 16, column 16]\n *&a:int=(n$5 * 2) [line 16, column 12]\n n$6=*&a:int [line 16, column 12]\n n$3=*&a:int [line 16, column 31]\n *&a:int=(n$3 + 1) [line 16, column 31]\n *&b:int=(7 * n$3) [line 16, column 23]\n n$4=*&b:int [line 16, column 23]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_5" -> "comma_2.aa5fd44d8dfe7804_6" ;
"comma_2.aa5fd44d8dfe7804_6" [label="6: BinaryOperatorStmt: Comma \n SKIP\n n$1=*&a:int [line 16, column 36]\n n$2=*&b:int [line 16, column 40]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_6" -> "comma_2.aa5fd44d8dfe7804_8" ;
"comma_2.aa5fd44d8dfe7804_7" [label="7: DeclStmt \n VARIABLE_DECLARED(d:int); [line 16, column 3]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_7" -> "comma_2.aa5fd44d8dfe7804_5" ;
"comma_2.aa5fd44d8dfe7804_8" [label="8: DeclStmt \n SKIP\n *&d:int=((n$1 + n$2) + 9) [line 16, column 3]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_5" -> "comma_2.aa5fd44d8dfe7804_3" ;
"comma_2.aa5fd44d8dfe7804_6" [label="6: DeclStmt \n VARIABLE_DECLARED(b:int); [line 15, column 3]\n *&b:int=7 [line 15, column 3]\n " shape="box"]
"comma_2.aa5fd44d8dfe7804_8" -> "comma_2.aa5fd44d8dfe7804_3" ;
"comma_2.aa5fd44d8dfe7804_9" [label="9: DeclStmt \n VARIABLE_DECLARED(b:int); [line 15, column 3]\n *&b:int=7 [line 15, column 3]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_6" -> "comma_2.aa5fd44d8dfe7804_5" ;
"comma_2.aa5fd44d8dfe7804_7" [label="7: DeclStmt \n VARIABLE_DECLARED(a:int); [line 15, column 3]\n *&a:int=9 [line 15, column 3]\n " shape="box"]
"comma_2.aa5fd44d8dfe7804_9" -> "comma_2.aa5fd44d8dfe7804_7" ;
"comma_2.aa5fd44d8dfe7804_10" [label="10: DeclStmt \n VARIABLE_DECLARED(a:int); [line 15, column 3]\n *&a:int=9 [line 15, column 3]\n " shape="box"]


"comma_2.aa5fd44d8dfe7804_7" -> "comma_2.aa5fd44d8dfe7804_6" ;
"comma_2.aa5fd44d8dfe7804_10" -> "comma_2.aa5fd44d8dfe7804_9" ;
"comma_3.94b9d12e6a2f1dbb_1" [label="1: Start comma_3\nFormals: \nLocals: d:int c:int b:int a:int \n " color=yellow style=filled]


"comma_3.94b9d12e6a2f1dbb_1" -> "comma_3.94b9d12e6a2f1dbb_8" ;
"comma_3.94b9d12e6a2f1dbb_1" -> "comma_3.94b9d12e6a2f1dbb_12" ;
"comma_3.94b9d12e6a2f1dbb_2" [label="2: Exit comma_3 \n " color=yellow style=filled]


Expand All @@ -69,20 +89,36 @@ digraph cfg {


"comma_3.94b9d12e6a2f1dbb_4" -> "comma_3.94b9d12e6a2f1dbb_2" ;
"comma_3.94b9d12e6a2f1dbb_5" [label="5: DeclStmt \n VARIABLE_DECLARED(d:int); [line 22, column 3]\n n$1=*&a:int [line 22, column 16]\n *&a:int=(n$1 * 2) [line 22, column 12]\n n$2=*&a:int [line 22, column 12]\n n$3=*&a:int [line 22, column 31]\n *&a:int=(n$3 + 1) [line 22, column 31]\n *&b:int=(7 * n$3) [line 22, column 23]\n n$4=*&b:int [line 22, column 23]\n n$5=*&a:int [line 22, column 40]\n n$6=*&b:int [line 22, column 44]\n *&c:int=((n$5 + n$6) + 9) [line 22, column 36]\n n$7=*&c:int [line 22, column 36]\n n$8=*&c:int [line 22, column 51]\n *&d:int=n$8 [line 22, column 3]\n " shape="box"]
"comma_3.94b9d12e6a2f1dbb_5" [label="5: BinaryOperatorStmt: Comma \n n$7=*&a:int [line 22, column 16]\n *&a:int=(n$7 * 2) [line 22, column 12]\n n$8=*&a:int [line 22, column 12]\n n$5=*&a:int [line 22, column 31]\n *&a:int=(n$5 + 1) [line 22, column 31]\n *&b:int=(7 * n$5) [line 22, column 23]\n n$6=*&b:int [line 22, column 23]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_5" -> "comma_3.94b9d12e6a2f1dbb_6" ;
"comma_3.94b9d12e6a2f1dbb_6" [label="6: BinaryOperatorStmt: Comma \n SKIP\n n$2=*&a:int [line 22, column 40]\n n$3=*&b:int [line 22, column 44]\n *&c:int=((n$2 + n$3) + 9) [line 22, column 36]\n n$4=*&c:int [line 22, column 36]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_6" -> "comma_3.94b9d12e6a2f1dbb_7" ;
"comma_3.94b9d12e6a2f1dbb_7" [label="7: BinaryOperatorStmt: Comma \n SKIP\n n$1=*&c:int [line 22, column 51]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_7" -> "comma_3.94b9d12e6a2f1dbb_9" ;
"comma_3.94b9d12e6a2f1dbb_8" [label="8: DeclStmt \n VARIABLE_DECLARED(d:int); [line 22, column 3]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_8" -> "comma_3.94b9d12e6a2f1dbb_5" ;
"comma_3.94b9d12e6a2f1dbb_9" [label="9: DeclStmt \n SKIP\n *&d:int=n$1 [line 22, column 3]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_5" -> "comma_3.94b9d12e6a2f1dbb_3" ;
"comma_3.94b9d12e6a2f1dbb_6" [label="6: DeclStmt \n VARIABLE_DECLARED(c:int); [line 21, column 3]\n *&c:int=3 [line 21, column 3]\n " shape="box"]
"comma_3.94b9d12e6a2f1dbb_9" -> "comma_3.94b9d12e6a2f1dbb_3" ;
"comma_3.94b9d12e6a2f1dbb_10" [label="10: DeclStmt \n VARIABLE_DECLARED(c:int); [line 21, column 3]\n *&c:int=3 [line 21, column 3]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_6" -> "comma_3.94b9d12e6a2f1dbb_5" ;
"comma_3.94b9d12e6a2f1dbb_7" [label="7: DeclStmt \n VARIABLE_DECLARED(b:int); [line 21, column 3]\n *&b:int=7 [line 21, column 3]\n " shape="box"]
"comma_3.94b9d12e6a2f1dbb_10" -> "comma_3.94b9d12e6a2f1dbb_8" ;
"comma_3.94b9d12e6a2f1dbb_11" [label="11: DeclStmt \n VARIABLE_DECLARED(b:int); [line 21, column 3]\n *&b:int=7 [line 21, column 3]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_7" -> "comma_3.94b9d12e6a2f1dbb_6" ;
"comma_3.94b9d12e6a2f1dbb_8" [label="8: DeclStmt \n VARIABLE_DECLARED(a:int); [line 21, column 3]\n *&a:int=9 [line 21, column 3]\n " shape="box"]
"comma_3.94b9d12e6a2f1dbb_11" -> "comma_3.94b9d12e6a2f1dbb_10" ;
"comma_3.94b9d12e6a2f1dbb_12" [label="12: DeclStmt \n VARIABLE_DECLARED(a:int); [line 21, column 3]\n *&a:int=9 [line 21, column 3]\n " shape="box"]


"comma_3.94b9d12e6a2f1dbb_8" -> "comma_3.94b9d12e6a2f1dbb_7" ;
"comma_3.94b9d12e6a2f1dbb_12" -> "comma_3.94b9d12e6a2f1dbb_11" ;
}
7 changes: 7 additions & 0 deletions infer/tests/codetoanalyze/cpp/pulse/uninit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,10 @@ class Uninit4 {
};

void construct_unint4_ok(Uninit3 uninit3) { Uninit4 uninit4(uninit3); }

int dummy_func(int);

void comma_operator_ok() {
int i, j;
i = ({ dummy_func(42); }), j = ({ dummy_func(i); });
}

0 comments on commit 645829c

Please sign in to comment.