[frontend][c++] Translate pointer-to-member expressions

Summary:
This diff translates C++ pointer-to-member expressions [5.5] to
pointer arithmetic.

Reviewed By: mbouaziz

Differential Revision: D6132554

fbshipit-source-id: 9b77a4c
master
Josh Berdine 7 years ago committed by Facebook Github Bot
parent df0491272c
commit c1e742536d

@ -87,9 +87,11 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr: Sil.instr) =
ap ap
| [] -> | [] ->
L.(die InternalError) 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 in
Instr (Assign (lhs_access_path, exp_of_sil rhs_exp typ, loc)) Instr (Assign (lhs_access_path, exp_of_sil rhs_exp typ, loc))
| Call (ret_opt, call_exp, formals, loc, call_flags) -> | Call (ret_opt, call_exp, formals, loc, call_flags) ->

@ -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 binary_operation_instruction boi e1 typ e2 loc =
let binop_exp op = Exp.BinOp (op, e1, e2) in let binop_exp op = Exp.BinOp (op, e1, e2) in
match boi.Clang_ast_t.boi_kind with 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 -> | `Add ->
(binop_exp Binop.PlusA, []) (binop_exp Binop.PlusA, [])
| `Mul -> | `Mul ->
@ -115,13 +125,6 @@ let binary_operation_instruction boi e1 typ e2 loc =
| `XorAssign | `XorAssign
| `OrAssign -> | `OrAssign ->
compound_assignment_binary_operation_instruction boi e1 typ e2 loc 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 = let unary_operation_instruction translation_unit_context uoi e typ loc =

@ -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 <typename E>
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<item> l(&item::next);
item i;
l.add(&i);
l.add_byref(i);
}
Loading…
Cancel
Save