Skip to content

Commit 6f8cafd

Browse files
authored
Merge pull request #4944 from smowton/smowton/admin/field-sensitivity-tests
Add field-sensitivity tests
2 parents 24a3d2a + ab6ca36 commit 6f8cafd

File tree

26 files changed

+430
-0
lines changed

26 files changed

+430
-0
lines changed
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a;
12+
a.x = argc;
13+
a.y = argc + 1;
14+
assert(a.x == argc);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a!0@1#2\.\.x = main::argc!0@1#1
5+
main::1::a!0@1#2\.\.y = 1 \+ main::argc!0@1#1
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
main::1::a!\d+@\d+#\d+\.x
10+
main::1::a!\d+@\d+#\d+\.y
11+
--
12+
Fields A::x and A::y should be referred to as atomic symbols (a..x and a..y) but not using
13+
member operators (a.x and a.y).
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
int z;
8+
};
9+
10+
int main(int argc, char **argv)
11+
{
12+
struct A a1, a2;
13+
char *field = (argc % 2 ? (char *)&a1.y : (char *)&a2.z) + 1;
14+
*field = (char)argc;
15+
assert(a1.y == argc);
16+
assert(a2.z == argc);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.y =
5+
main::1::a2!0@1#2\.\.z =
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
main::1::a[12]!\d+@\d+#\d+\.[xyz]
10+
--
11+
Fields A::y and A::z should be referred to as atomic symbols (a[12]..y and a[12]..z) but not using
12+
member operators (a[12].[xyz]).
13+
While the field is aliased with a different type, the typecast is successfully reduced to address just
14+
one field, rather than using a byte-update operation against the whole structure.
15+
This is like field-sensitivity8 except the pointer leads into the middle of a field.
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a1, a2;
12+
a1.x = argc;
13+
a1.y = argc + 1;
14+
a2 = a1;
15+
assert(a2.x == argc);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.x = main::argc!0@1#1
5+
main::1::a1!0@1#2\.\.y = 1 \+ main::argc!0@1#1
6+
main::1::a2!0@1#2\.\.x = main::1::a1!0@1#2\.\.x
7+
main::1::a2!0@1#2\.\.y = main::1::a1!0@1#2\.\.y
8+
^EXIT=0$
9+
^SIGNAL=0$
10+
--
11+
main::1::a[12]!\d+@\d+#\d+\.[xy]
12+
--
13+
Fields A::x and A::y should be referred to as atomic symbols (a[12]..x and a[12]..y) but not using
14+
member operators (a[12].x and a[12].y).
15+
This test looks at the particular case of whole-struct assignment.
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a1, a2;
12+
a1.x = argc;
13+
a1.y = argc + 1;
14+
struct A *aptr = argc % 2 ? &a1 : &a2;
15+
*aptr = a1;
16+
assert(a2.x == argc);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.x = main::argc!0@1#1
5+
main::1::a1!0@1#2\.\.y = 1 \+ main::argc!0@1#1
6+
main::1::a1!0@1#3\.\.x = main::1::a1!0@1#2\.\.x
7+
main::1::a1!0@1#3\.\.y = main::1::a1!0@1#2\.\.y
8+
main::1::a2!0@1#2\.\.x =
9+
main::1::a2!0@1#2\.\.y =
10+
^EXIT=0$
11+
^SIGNAL=0$
12+
--
13+
main::1::a[12]!\d+@\d+#\d+\.[xy]
14+
--
15+
Fields A::x and A::y should be referred to as atomic symbols (a[12]..x and a[12]..y) but not using
16+
member operators (a[12].x and a[12].y).
17+
This test looks at the particular case of whole-struct assignment when the target of the assignment
18+
is uncertain due to pointer indirection.
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
struct B
10+
{
11+
struct A a;
12+
int z;
13+
};
14+
15+
int main(int argc, char **argv)
16+
{
17+
struct B b1, b2;
18+
b1.a.x = argc;
19+
b1.a.y = argc + 1;
20+
struct A *aptr = argc % 2 ? &b1.a : &b2.a;
21+
*aptr = b1.a;
22+
assert(b2.a.x == argc);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::b1!0@1#2\.\.a\.\.x = main::argc!0@1#1
5+
main::1::b1!0@1#2\.\.a\.\.y = 1 \+ main::argc!0@1#1
6+
main::1::b1!0@1#3\.\.a\.\.x = main::1::b1!0@1#2\.\.a\.\.x
7+
main::1::b1!0@1#3\.\.a\.\.y = main::1::b1!0@1#2\.\.a\.\.y
8+
main::1::b2!0@1#2\.\.a\.\.x =
9+
main::1::b2!0@1#2\.\.a\.\.y =
10+
^EXIT=0$
11+
^SIGNAL=0$
12+
--
13+
main::1::b[12]!\d+@\d+#\d+\.a
14+
--
15+
Fields A::x and A::y should be referred to as atomic symbols (b[12]..a..x and b[12]..a..y) but not using
16+
member operators (b[12].a.x and b[12].a.y).
17+
This test looks at the particular case of whole-struct assignment when the target of the assignment
18+
is uncertain due to pointer indirection.
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a1, a2;
12+
struct A *aptr = argc % 2 ? &a1 : &a2;
13+
aptr->x = argc;
14+
aptr->y = argc + 1;
15+
assert(a1.x == argc);
16+
assert(a2.x == argc);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.x =
5+
main::1::a1!0@1#2\.\.y =
6+
main::1::a2!0@1#2\.\.x =
7+
main::1::a2!0@1#2\.\.y =
8+
^EXIT=0$
9+
^SIGNAL=0$
10+
--
11+
main::1::a[12]!\d+@\d+#\d+\.[xy]
12+
--
13+
Fields A::x and A::y should be referred to as atomic symbols (a[12]..x and a[12]..y) but not using
14+
member operators (a[12].x and a[12].y).
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a1, a2, a3, a4;
12+
struct A *aptr = argc % 2 ? &a1 : argc % 3 ? &a2 : argc % 5 ? &a3 : &a4;
13+
aptr->x = argc;
14+
aptr->y = argc + 1;
15+
assert(a1.x == argc);
16+
assert(a2.x == argc);
17+
assert(a3.x == argc);
18+
assert(a4.x == argc);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.x =
5+
main::1::a1!0@1#2\.\.y =
6+
main::1::a2!0@1#2\.\.x =
7+
main::1::a2!0@1#2\.\.y =
8+
main::1::a3!0@1#2\.\.x =
9+
main::1::a3!0@1#2\.\.y =
10+
main::1::a4!0@1#2\.\.x =
11+
main::1::a4!0@1#2\.\.y =
12+
^EXIT=0$
13+
^SIGNAL=0$
14+
--
15+
main::1::a[1234]!\d+@\d+#\d+\.[xy]
16+
--
17+
Fields A::x and A::y should be referred to as atomic symbols (a[1234]..x and a[1234]..y) but not using
18+
member operators (a[1234].x and a[1234].y).
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A a;
12+
int *field = argc % 2 ? &a.x : &a.y;
13+
*field = argc;
14+
assert(a.x == argc);
15+
assert(a.y == argc);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FUTURE
2+
test.c
3+
--show-vcc
4+
main::1::a!0@1#2\.\.x =
5+
main::1::a!0@1#2\.\.y =
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
main::1::a!\d+@\d+#\d+\.x
10+
main::1::a!\d+@\d+#\d+\.y
11+
--
12+
Fields A::x and A::y should be referred to as atomic symbols (a..x and a..y) but not using
13+
member operators (a.x and a.y).
14+
Currently this generates a byte_update operation followed by field expansion; could be improved
15+
if value_sett kept track of a finite set of constant offsets rather than degrading to unknown-offset
16+
whenever multiple offsets into the same allocation are merged.
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int head;
6+
struct A *tail;
7+
};
8+
9+
int main(int argc, char **argv)
10+
{
11+
struct A node1, node2, node3;
12+
node1.tail = argc % 2 ? &node2 : &node3;
13+
node2.tail = argc % 3 ? &node1 : &node3;
14+
node3.tail = argc % 5 ? &node1 : &node2;
15+
node1.tail->tail->tail->head = argc;
16+
assert(node1.head == argc);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::node1!0@1#2\.\.head =
5+
main::1::node2!0@1#2\.\.head =
6+
main::1::node3!0@1#2\.\.head =
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
10+
main::1::node[123]!\d+@\d+#\d+\.head
11+
main::1::node[123]!\d+@\d+#\d+\.tail
12+
--
13+
Fields A::head and A::tail should be referred to as atomic symbols (node[123]..head and node[123]..tail)
14+
but not using member operators (node[123].(head)|(tail))
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
struct B
10+
{
11+
struct A a;
12+
};
13+
14+
int main(int argc, char **argv)
15+
{
16+
struct B b1, b2;
17+
struct A *aptr = argc % 2 ? &b1.a : &b2.a;
18+
aptr->x = argc;
19+
assert(b1.a.x == argc);
20+
assert(b2.a.x == argc);
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::b1!0@1#2\.\.a\.\.x =
5+
main::1::b2!0@1#2\.\.a\.\.x =
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
main::1::b1!\d+@\d+#\d+\.a
10+
main::1::b2!\d+@\d+#\d+\.a
11+
--
12+
Field A::x should be referred to as atomic symbols (b[12]..x) but not using
13+
member operators (b[12].a)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
struct A
4+
{
5+
int x;
6+
int y;
7+
int z;
8+
};
9+
10+
int main(int argc, char **argv)
11+
{
12+
struct A a1, a2;
13+
int *field = argc % 2 ? &a1.y : &a2.z;
14+
*field = argc;
15+
assert(a1.y == argc);
16+
assert(a2.z == argc);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
test.c
3+
--show-vcc
4+
main::1::a1!0@1#2\.\.y =
5+
main::1::a2!0@1#2\.\.z =
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
main::1::a[12]!\d+@\d+#\d+\.[xyz]
10+
--
11+
Fields A::y and A::z should be referred to as atomic symbols (a[12]..y and a[12]..z) but not using
12+
member operators (a[12].[xyz]).
13+
Note the contrast with field-sensitivity4, where the fields the pointer may address are part of the
14+
same allocated object resulting in inability to resolve them, contrasting against this test where
15+
the fields belong to different objects.

0 commit comments

Comments
 (0)