diff --git a/infer/src/IR/HilInstr.ml b/infer/src/IR/HilInstr.ml index bcf9f52ad..f23617617 100644 --- a/infer/src/IR/HilInstr.ml +++ b/infer/src/IR/HilInstr.ml @@ -87,9 +87,11 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr: Sil.instr) = ap | [] -> L.(die InternalError) - "Invalid pointer arithmetic expression %a used as LHS" Exp.pp lhs_exp ) + "Invalid pointer arithmetic expression %a used as LHS at %a" Exp.pp lhs_exp + Location.pp_file_pos loc ) | _ -> - L.(die InternalError) "Non-assignable LHS expression %a" Exp.pp lhs_exp + L.(die InternalError) + "Non-assignable LHS expression %a at %a" Exp.pp lhs_exp Location.pp_file_pos loc in Instr (Assign (lhs_access_path, exp_of_sil rhs_exp typ, loc)) | Call (ret_opt, call_exp, formals, loc, call_flags) -> diff --git a/infer/src/clang/cArithmetic_trans.ml b/infer/src/clang/cArithmetic_trans.ml index ed258d71d..2a37d001f 100644 --- a/infer/src/clang/cArithmetic_trans.ml +++ b/infer/src/clang/cArithmetic_trans.ml @@ -64,6 +64,16 @@ let compound_assignment_binary_operation_instruction boi e1 typ e2 loc = let binary_operation_instruction boi e1 typ e2 loc = let binop_exp op = Exp.BinOp (op, e1, e2) in match boi.Clang_ast_t.boi_kind with + (* Note: Pointers to members that are not statically known are not + expressible in Sil. The translation of the PtrMem ops treats the field as + an integer offset, which is itself semantically ok though too low-level, + but the translation of the argument expressions does not compute such + offsets and instead passes the member pointer at type 'void'. *) + | `PtrMemD -> + (binop_exp Binop.PlusPI, []) + | `PtrMemI -> + let id = Ident.create_fresh Ident.knormal in + (Exp.BinOp (PlusPI, Exp.Var id, e2), [Sil.Load (id, e1, typ, loc)]) | `Add -> (binop_exp Binop.PlusA, []) | `Mul -> @@ -115,13 +125,6 @@ let binary_operation_instruction boi e1 typ e2 loc = | `XorAssign | `OrAssign -> compound_assignment_binary_operation_instruction boi e1 typ e2 loc - (* We should not get here. *) - (* These should be treated by compound_assignment_binary_operation_instruction*) - | bok -> - L.(debug Capture Medium) - "@\nWARNING: Missing translation for Binary Operator Kind %s. Construct ignored...@\n" - (Clang_ast_j.string_of_binary_operator_kind bok) ; - (Exp.minus_one, []) let unary_operation_instruction translation_unit_context uoi e typ loc = diff --git a/infer/tests/codetoanalyze/cpp/shared/reference/ptr_mem.cpp b/infer/tests/codetoanalyze/cpp/shared/reference/ptr_mem.cpp new file mode 100644 index 000000000..f6fafad2a --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/shared/reference/ptr_mem.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +struct item { + int data; + item* next; +}; + +template +struct List { + List(E* E::*next_ptr) : head(nullptr), next_ptr(next_ptr) {} + + void add(E* e) { + e->*next_ptr = head; + head = e; + } + + void add_byref(E& e) { + e.*next_ptr = head; + head = &e; + } + + E* head; + E* E::*next_ptr; +}; + +int main() { + List l(&item::next); + + item i; + l.add(&i); + l.add_byref(i); +}