xref: /llvm-project/compiler-rt/test/tysan/struct.c (revision 641fbf1524338c86c952ebb1ec8d2b497ada3cef)
1*641fbf15SFlorian Hahn // RUN: %clang_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
2*641fbf15SFlorian Hahn // RUN: FileCheck %s < %t.out
3*641fbf15SFlorian Hahn 
4*641fbf15SFlorian Hahn #include <stdio.h>
5*641fbf15SFlorian Hahn 
6*641fbf15SFlorian Hahn typedef struct S1 {
7*641fbf15SFlorian Hahn   int i1;
8*641fbf15SFlorian Hahn } s1;
9*641fbf15SFlorian Hahn typedef struct S2 {
10*641fbf15SFlorian Hahn   int i2;
11*641fbf15SFlorian Hahn } s2;
12*641fbf15SFlorian Hahn 
13*641fbf15SFlorian Hahn void g(int *i) {
14*641fbf15SFlorian Hahn   *i = 5;
15*641fbf15SFlorian Hahn   printf("%i\n", *i);
16*641fbf15SFlorian Hahn }
17*641fbf15SFlorian Hahn 
18*641fbf15SFlorian Hahn void h(char *c) {
19*641fbf15SFlorian Hahn   *c = 5;
20*641fbf15SFlorian Hahn   printf("%i\n", (int)*c);
21*641fbf15SFlorian Hahn }
22*641fbf15SFlorian Hahn 
23*641fbf15SFlorian Hahn void f(s1 *s1p, s2 *s2p) {
24*641fbf15SFlorian Hahn   s1p->i1 = 2;
25*641fbf15SFlorian Hahn   s2p->i2 = 3;
26*641fbf15SFlorian Hahn   // CHECK: ERROR: TypeSanitizer: type-aliasing-violation
27*641fbf15SFlorian Hahn   // CHECK: WRITE of size 4 at {{.*}} with type int (in S2 at offset 0) accesses an existing object of type int (in S1 at offset 0)
28*641fbf15SFlorian Hahn   // CHECK: {{#0 0x.* in f .*struct.c:}}[[@LINE-3]]
29*641fbf15SFlorian Hahn   printf("%i\n", s1p->i1);
30*641fbf15SFlorian Hahn }
31*641fbf15SFlorian Hahn 
32*641fbf15SFlorian Hahn int main() {
33*641fbf15SFlorian Hahn   s1 s = {.i1 = 1};
34*641fbf15SFlorian Hahn   f(&s, (s2 *)&s);
35*641fbf15SFlorian Hahn   g(&s.i1);
36*641fbf15SFlorian Hahn   h((char *)&s.i1);
37*641fbf15SFlorian Hahn }
38*641fbf15SFlorian Hahn 
39*641fbf15SFlorian Hahn // CHECK-NOT: ERROR: TypeSanitizer: type-aliasing-violation
40