From b289d240f5ef836916476196e9b5b120c94052b5 Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Thu, 28 Jan 2021 07:26:59 -0800 Subject: [PATCH] [frontend] Fix incorrect order of statements (implicit cast) Reviewed By: jvillard Differential Revision: D26126418 fbshipit-source-id: e3e24c3dc --- infer/src/clang/cTrans.ml | 6 +++- infer/tests/codetoanalyze/c/pulse/frontend.c | 37 ++++++++++++++++++++ infer/tests/codetoanalyze/c/pulse/issues.exp | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 infer/tests/codetoanalyze/c/pulse/frontend.c diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index ade33615f..96b0a54ff 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1094,7 +1094,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s to avoid an incorrect statement order. *) let e1_control = match (binary_operator_info.Clang_ast_t.boi_kind, s2) with - | `Assign, Clang_ast_t.(ConditionalOperator _ | UnaryOperator _) -> + | ( `Assign + , Clang_ast_t.( + ( ConditionalOperator _ + | UnaryOperator _ + | ImplicitCastExpr (_, ([ConditionalOperator _] | [UnaryOperator _]), _, _) )) ) -> let trans_state' = PriorityNode.try_claim_priority_node trans_state' stmt_info in PriorityNode.compute_controls_to_parent trans_state' sil_loc node_name stmt_info [res_trans_e1.control] diff --git a/infer/tests/codetoanalyze/c/pulse/frontend.c b/infer/tests/codetoanalyze/c/pulse/frontend.c new file mode 100644 index 000000000..69aea19a3 --- /dev/null +++ b/infer/tests/codetoanalyze/c/pulse/frontend.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +void assign_implicit_cast_ok() { + bool* b = (bool*)malloc(sizeof(bool)); + uint16_t i = 1; + if (b) { + *b = true; + *b = !i; + if (*b) { + int* p = 0; + *p = 5; + } + free(b); + } +} + +void assign_implicit_cast_bad() { + bool* b = (bool*)malloc(sizeof(bool)); + uint16_t i = 0; + if (b) { + *b = false; + *b = !i; + if (*b) { + int* p = 0; + *p = 5; + } + free(b); + } +} diff --git a/infer/tests/codetoanalyze/c/pulse/issues.exp b/infer/tests/codetoanalyze/c/pulse/issues.exp index 5e7c0e95f..71e76c6c8 100644 --- a/infer/tests/codetoanalyze/c/pulse/issues.exp +++ b/infer/tests/codetoanalyze/c/pulse/issues.exp @@ -1,3 +1,4 @@ +codetoanalyze/c/pulse/frontend.c, assign_implicit_cast_bad, 8, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, if_freed_invalid_latent, 3, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,parameter `y` of if_freed_invalid_latent,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `y` of if_freed_invalid_latent,invalid access occurs here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad, 0, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,when calling `create_p` here,allocated by call to `malloc` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad2, 4, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc` (modelled),allocation part of the trace ends here,memory becomes unreachable here]