Summary: When there was an assignment of C struct, `x = y;`, it was translated to the statements of load and store. ``` n$0 = *y *x = n$0 ``` However, this is incorrect in Sil, because a struct is not a value that can be assigned to registers. This diff fixes the translation as assignments of each field values : ``` n$0 = *y.field1 *x.field1 = n$0 n$0 = *y.field2 *x.field2 = n$0 ... ``` It copies field values of C structs on: * assign statement * return statement * declarations. It supports nested structs. Reviewed By: jvillard Differential Revision: D25952894 fbshipit-source-id: 355f8db9cmaster
parent
e11b1b49b3
commit
1bce54aaf3
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct s {
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
void struct_copy_Ok() {
|
||||
int a[5];
|
||||
struct s x, y;
|
||||
x.a = 3;
|
||||
x.b = 5;
|
||||
y = x;
|
||||
a[y.a] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_Bad() {
|
||||
int a[3];
|
||||
struct s x, y;
|
||||
x.a = 3;
|
||||
x.b = 5;
|
||||
y = x;
|
||||
a[y.b] = 0;
|
||||
}
|
||||
|
||||
struct t {
|
||||
struct s s;
|
||||
int c;
|
||||
};
|
||||
|
||||
void nested_struct_copy_Ok() {
|
||||
int a[7];
|
||||
struct t x, y;
|
||||
x.s.a = 3;
|
||||
x.s.b = 5;
|
||||
x.c = 7;
|
||||
y = x;
|
||||
a[y.s.a] = 0;
|
||||
}
|
||||
|
||||
void nested_struct_copy_Bad() {
|
||||
int a[3];
|
||||
struct t x, y;
|
||||
x.s.a = 3;
|
||||
x.s.b = 5;
|
||||
x.c = 7;
|
||||
y = x;
|
||||
a[y.s.b] = 0;
|
||||
}
|
||||
|
||||
struct s get_struct() {
|
||||
struct s x;
|
||||
x.a = 3;
|
||||
x.b = 5;
|
||||
return x;
|
||||
}
|
||||
|
||||
void struct_copy_from_function_call_Ok() {
|
||||
int a[5];
|
||||
struct s x;
|
||||
x = get_struct();
|
||||
a[x.a] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_from_function_call_Bad() {
|
||||
int a[3];
|
||||
struct s x;
|
||||
x = get_struct();
|
||||
a[x.b] = 0;
|
||||
}
|
||||
|
||||
struct s get_struct_wrapper() {
|
||||
return get_struct();
|
||||
}
|
||||
|
||||
void struct_copy_from_wrapper_call_Ok() {
|
||||
int a[5];
|
||||
struct s x;
|
||||
x = get_struct_wrapper();
|
||||
a[x.a] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_from_wrapper_call_Bad() {
|
||||
int a[3];
|
||||
struct s x;
|
||||
x = get_struct_wrapper();
|
||||
a[x.b] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_decl_Ok() {
|
||||
int a[5];
|
||||
struct s x;
|
||||
x.a = 3;
|
||||
x.b = 5;
|
||||
struct s y = x;
|
||||
a[y.a] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_decl_Bad() {
|
||||
int a[3];
|
||||
struct s x;
|
||||
x.a = 3;
|
||||
x.b = 5;
|
||||
struct s y = x;
|
||||
a[y.b] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_decl_by_function_Ok() {
|
||||
int a[5];
|
||||
struct s x = get_struct();
|
||||
a[x.a] = 0;
|
||||
}
|
||||
|
||||
void struct_copy_decl_by_function_Bad() {
|
||||
int a[3];
|
||||
struct s x = get_struct();
|
||||
a[x.b] = 0;
|
||||
}
|
Loading…
Reference in new issue