From 645829c991711c903fdccac6f83ff8d53563ab37 Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Tue, 9 Apr 2024 06:00:13 -0700 Subject: [PATCH] [clang] Force evaluation order of the comma operator 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 --- infer/src/clang/cTrans.ml | 14 ++++ .../c/frontend/comma/comma.c.dot | 80 ++++++++++++++----- .../tests/codetoanalyze/cpp/pulse/uninit.cpp | 7 ++ 3 files changed, 79 insertions(+), 22 deletions(-) diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index cbdc2154be1..46150f57690 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -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} = diff --git a/infer/tests/codetoanalyze/c/frontend/comma/comma.c.dot b/infer/tests/codetoanalyze/c/frontend/comma/comma.c.dot index 2275c5a1b20..988c949d8b7 100644 --- a/infer/tests/codetoanalyze/c/frontend/comma/comma.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/comma/comma.c.dot @@ -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] @@ -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] @@ -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] @@ -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" ; } diff --git a/infer/tests/codetoanalyze/cpp/pulse/uninit.cpp b/infer/tests/codetoanalyze/cpp/pulse/uninit.cpp index 6d71594a149..e812b2a5d8a 100644 --- a/infer/tests/codetoanalyze/cpp/pulse/uninit.cpp +++ b/infer/tests/codetoanalyze/cpp/pulse/uninit.cpp @@ -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); }); +}