add different handling for C++ increment/decrement operators

Summary: public
In C pre-increment/decrement returns rvalue, but in C++ it returns lvalue.
Make translation aware of the difference and treat these cases differently.

Reviewed By: ddino

Differential Revision: D2575136

fb-gh-sync-id: 952c095
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-7
parent 982616148e
commit a7a332ea51

@ -151,7 +151,11 @@ let unary_operation_instruction uoi e typ loc =
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_plus_1 = Sil.BinOp(Sil.PlusA, Sil.Var id, Sil.Const(Sil.Cint (Sil.Int.one))) in
([id], e_plus_1, instr1::[Sil.Set (e, typ, e_plus_1, loc)])
let exp = if General_utils.is_cpp_translation !CFrontend_config.language then
e
else
e_plus_1 in
([id], exp, instr1::[Sil.Set (e, typ, e_plus_1, loc)])
| `PostDec ->
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
@ -161,7 +165,11 @@ let unary_operation_instruction uoi e typ loc =
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_minus_1 = Sil.BinOp(Sil.MinusA, Sil.Var id, Sil.Const(Sil.Cint (Sil.Int.one))) in
([id], e_minus_1, instr1::[Sil.Set (e, typ, e_minus_1, loc)])
let exp = if General_utils.is_cpp_translation !CFrontend_config.language then
e
else
e_minus_1 in
([id], exp, instr1::[Sil.Set (e, typ, e_minus_1, loc)])
| `Not -> ([], un_exp (Sil.BNot), [])
| `Minus -> ([], un_exp (Sil.Neg), [])
| `Plus -> ([], e, [])

@ -0,0 +1,16 @@
/*
* Copyright (c) 2015 - 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.
*/
int test() {
int a = 3;
int b = ++a;
int c = a++;
int d = --a;
int e = a--;
}

@ -0,0 +1,29 @@
digraph iCFG {
7 [label="7: DeclStmt \n *&a:int =3 [line 11]\n " shape="box"]
7 -> 6 ;
6 [label="6: DeclStmt \n n$3=*&a:int [line 12]\n *&a:int =(n$3 + 1) [line 12]\n *&b:int =(n$3 + 1) [line 12]\n REMOVE_TEMPS(n$3); [line 12]\n NULLIFY(&b,false); [line 12]\n " shape="box"]
6 -> 5 ;
5 [label="5: DeclStmt \n n$2=*&a:int [line 13]\n *&a:int =(n$2 + 1) [line 13]\n *&c:int =n$2 [line 13]\n REMOVE_TEMPS(n$2); [line 13]\n NULLIFY(&c,false); [line 13]\n " shape="box"]
5 -> 4 ;
4 [label="4: DeclStmt \n n$1=*&a:int [line 14]\n *&a:int =(n$1 - 1) [line 14]\n *&d:int =(n$1 - 1) [line 14]\n REMOVE_TEMPS(n$1); [line 14]\n NULLIFY(&d,false); [line 14]\n " shape="box"]
4 -> 3 ;
3 [label="3: DeclStmt \n n$0=*&a:int [line 15]\n *&a:int =(n$0 - 1) [line 15]\n *&e:int =n$0 [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&a,false); [line 15]\n NULLIFY(&e,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit test \n " color=yellow style=filled]
1 [label="1: Start test\nFormals: \nLocals: e:int d:int c:int b:int a:int \n DECLARE_LOCALS(&return,&e,&d,&c,&b,&a); [line 10]\n NULLIFY(&a,false); [line 10]\n NULLIFY(&b,false); [line 10]\n NULLIFY(&c,false); [line 10]\n NULLIFY(&d,false); [line 10]\n NULLIFY(&e,false); [line 10]\n " color=yellow style=filled]
1 -> 7 ;
}

@ -0,0 +1,29 @@
digraph iCFG {
7 [label="7: DeclStmt \n *&a:int =3 [line 11]\n " shape="box"]
7 -> 6 ;
6 [label="6: DeclStmt \n n$4=*&a:int [line 12]\n *&a:int =(n$4 + 1) [line 12]\n n$5=*&a:int [line 12]\n *&b:int =n$5 [line 12]\n REMOVE_TEMPS(n$4,n$5); [line 12]\n NULLIFY(&b,false); [line 12]\n " shape="box"]
6 -> 5 ;
5 [label="5: DeclStmt \n n$3=*&a:int [line 13]\n *&a:int =(n$3 + 1) [line 13]\n *&c:int =n$3 [line 13]\n REMOVE_TEMPS(n$3); [line 13]\n NULLIFY(&c,false); [line 13]\n " shape="box"]
5 -> 4 ;
4 [label="4: DeclStmt \n n$1=*&a:int [line 14]\n *&a:int =(n$1 - 1) [line 14]\n n$2=*&a:int [line 14]\n *&d:int =n$2 [line 14]\n REMOVE_TEMPS(n$1,n$2); [line 14]\n NULLIFY(&d,false); [line 14]\n " shape="box"]
4 -> 3 ;
3 [label="3: DeclStmt \n n$0=*&a:int [line 15]\n *&a:int =(n$0 - 1) [line 15]\n *&e:int =n$0 [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&a,false); [line 15]\n NULLIFY(&e,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit test \n " color=yellow style=filled]
1 [label="1: Start test\nFormals: \nLocals: e:int d:int c:int b:int a:int \n DECLARE_LOCALS(&return,&e,&d,&c,&b,&a); [line 10]\n NULLIFY(&a,false); [line 10]\n NULLIFY(&b,false); [line 10]\n NULLIFY(&c,false); [line 10]\n NULLIFY(&d,false); [line 10]\n NULLIFY(&e,false); [line 10]\n " color=yellow style=filled]
1 -> 7 ;
}

@ -0,0 +1,21 @@
/*
* Copyright (c) 2015 - 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.
*/
void using_value() {
int v = 3;
int &r = ++v;
int &q = --v;
}
void using_ref() {
int v = 3;
int &vr = v;
int &r = ++vr;
int &q = --vr;
}

@ -0,0 +1,44 @@
digraph iCFG {
11 [label="11: DeclStmt \n *&v:int =3 [line 17]\n " shape="box"]
11 -> 10 ;
10 [label="10: DeclStmt \n *&vr:int &=&v [line 18]\n " shape="box"]
10 -> 9 ;
9 [label="9: DeclStmt \n n$2=*&vr:int & [line 19]\n n$3=*n$2:int [line 19]\n *n$2:int =(n$3 + 1) [line 19]\n *&r:int &=n$2 [line 19]\n REMOVE_TEMPS(n$2,n$3); [line 19]\n NULLIFY(&r,false); [line 19]\n " shape="box"]
9 -> 8 ;
8 [label="8: DeclStmt \n n$0=*&vr:int & [line 20]\n n$1=*n$0:int [line 20]\n *n$0:int =(n$1 - 1) [line 20]\n *&q:int &=n$0 [line 20]\n REMOVE_TEMPS(n$0,n$1); [line 20]\n NULLIFY(&q,false); [line 20]\n NULLIFY(&vr,false); [line 20]\n NULLIFY(&v,false); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="box"]
8 -> 7 ;
7 [label="7: Exit using_ref \n " color=yellow style=filled]
6 [label="6: Start using_ref\nFormals: \nLocals: q:int & r:int & vr:int & v:int \n DECLARE_LOCALS(&return,&q,&r,&vr,&v); [line 16]\n NULLIFY(&q,false); [line 16]\n NULLIFY(&r,false); [line 16]\n NULLIFY(&vr,false); [line 16]\n " color=yellow style=filled]
6 -> 11 ;
5 [label="5: DeclStmt \n *&v:int =3 [line 11]\n " shape="box"]
5 -> 4 ;
4 [label="4: DeclStmt \n n$1=*&v:int [line 12]\n *&v:int =(n$1 + 1) [line 12]\n *&r:int &=&v [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n NULLIFY(&r,false); [line 12]\n " shape="box"]
4 -> 3 ;
3 [label="3: DeclStmt \n n$0=*&v:int [line 13]\n *&v:int =(n$0 - 1) [line 13]\n *&q:int &=&v [line 13]\n REMOVE_TEMPS(n$0); [line 13]\n NULLIFY(&q,false); [line 13]\n NULLIFY(&v,false); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit using_value \n " color=yellow style=filled]
1 [label="1: Start using_value\nFormals: \nLocals: q:int & r:int & v:int \n DECLARE_LOCALS(&return,&q,&r,&v); [line 10]\n NULLIFY(&q,false); [line 10]\n NULLIFY(&r,false); [line 10]\n " color=yellow style=filled]
1 -> 5 ;
}

@ -49,4 +49,9 @@ public class NestedOperatorsTest {
frontendTest("assign_in_condition.c");
}
@Test
public void whenCaptureRunAssignWithIncrementThenDotFilesAreTheSame()
throws InterruptedException, IOException, InferException {
frontendTest("assign_with_increment.c");
}
}

@ -56,4 +56,11 @@ public class NestedOperatorsTest {
frontendTest("assign_in_condition.cpp");
}
@Test
public void whenCaptureRunAssignWithIncrementThenDotFilesAreTheSame()
throws InterruptedException, IOException, InferException {
// .dot file differs, but it's semantically equivalent to one produced by
// C compiler
frontendTest("assign_with_increment.cpp");
}
}

@ -65,6 +65,12 @@ public class ReferenceTest {
frontendTest("nested_assignment.cpp");
}
@Test
public void testIncrementDotFilesMatch()
throws InterruptedException, IOException, InferException {
frontendTest("increment.cpp");
}
@Test
public void testReferenceTypeE2EDotFilesMatch()
throws InterruptedException, IOException, InferException {

Loading…
Cancel
Save