summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/torture/pr65077.c
blob: f57356c60bbdc07c19703cc073f811dcf9f381a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/* { dg-do run } */

extern void abort (void);
extern void *memcpy(void *, const void *, __SIZE_TYPE__);

typedef struct {
    void *v1;
    void *v2;
    void *v3;
    union {
	void *f1;
	void *f2;
    } u;
} S;


S *getS();
void verify_p(void *p);
double *getP(void *p);

void memcpy_bug()
{
  S *s;
  double *p = getP(0);

  if (p) {
      int intSptr[sizeof(S*)/sizeof(int)];
      unsigned i = 0;
      for (i = 0; i < sizeof(intSptr)/sizeof(*intSptr); ++i) {
	  intSptr[i] = (int) p[i];
      }
      memcpy(&s, intSptr, sizeof(intSptr));
      (s)->u.f1 = p;
      verify_p((s)->u.f1);      
  } else {
      s = getS();
  }
  verify_p(s->u.f1);
}

double P[4];

double *getP(void *p) {
    union u {
	void *p;
	int i[2];
    } u;
    u.p = P;
    P[0] = u.i[0];
    P[1] = u.i[1];
    return P;
}

S *getS()
{
  return 0;
}

void verify_p(void *p)
{
  if (p != P)
    abort ();
}

int main(int argc, char *argv[])
{
    memcpy_bug();
    return 0;
}