1 /* { dg-do run } */
2 /* { dg-options "-Os" } */
3
4 /* Based on gethostbyname_r,
5 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
6 *
7 * Licensed under the LGPL v2.1, see the file COPYING.LIB
8 *
9 * Extraction / wrapping as test by
10 * Joern Rennecke <joern.rennecke@embecosm.com>
11 * Copyright (C) 2013 Free Software Foundation, Inc.
12 */
13
14 typedef unsigned size_t;
15 typedef int ssize_t;
16 typedef unsigned uint32_t;
17 struct resolv_answer {
18 char *dotted;
19 int atype;
20 int aclass;
21 int ttl;
22 int rdlength;
23 const unsigned char *rdata;
24 int rdoffset;
25 char* buf;
26 size_t buflen;
27 size_t add_count;
28 };
29 struct hostent
30 {
31 char *h_name;
32 char **h_aliases;
33 int h_addrtype;
34 int h_length;
35 char **h_addr_list;
36 };
37
38 int *__attribute__ ((noinline,weak)) nop (void * p) { return p; };
39 void __attribute__ ((noinline,weak)) seta (struct resolv_answer * p)
40 { p->atype = 1;}
41
42 int ghostbyname_r(
43 struct hostent *result_buf,
44 char *buf,
45 size_t buflen,
46 struct hostent **result,
47 int *h_errnop)
48 {
49 char **addr_list;
50 char **alias;
51 char *alias0;
52 int i0;
53 struct resolv_answer a;
54 int i;
55
56 *result = ((void *)0);
57
58 *h_errnop = -1;
59
60 if ((ssize_t)buflen <= 5)
61 return 34;
62
63 alias = (char **)buf;
64 addr_list = (char **)buf;
65
66 /* This got turned into branch with conditional move in delay slot. */
67 if ((ssize_t)buflen < 256)
68 return 34;
69
70
71 {
72 if (!nop(&i0)) {
73 result_buf->h_aliases = alias;
74 result_buf->h_addrtype = 2;
75 result_buf->h_length = 4;
76 result_buf->h_addr_list = addr_list;
77 *result = result_buf;
78 *h_errnop = 0;
79 return 0;
80 }
81 }
82
83
84 seta (&a);
85
86 if (a.atype == 1) {
87
88 int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1);
89
90 int ips_len = a.add_count * a.rdlength;
91
92 buflen -= (need_bytes + ips_len);
93 if ((ssize_t)buflen < 0) {
94 i = 34;
95 goto free_and_ret;
96 }
97
98 result_buf->h_addrtype = 2;
99 *result = result_buf;
100 *h_errnop = 0;
101 i = 0;
102 goto free_and_ret;
103 }
104
105 /* For cse, the 1 was is loaded into a call-saved register;
106 the load was hoisted into a delay slot before the conditional load,
107 clobbering result_buf, which (conditionally) lived in the same
108 call-saved register, because mark_referenced_resources considered the
109 destination of the COND_EXEC only clobbered, but not used. */
110 *h_errnop = 1;
111 *nop(&i0) = 1;
112 i = 2;
113
114 free_and_ret:
115 nop (&i0);
116 return i;
117 }
118
119 int
120 main ()
121 {
122 struct hostent buf, *res;
123 int i;
124 char c;
125 ghostbyname_r (&buf, &c, 1024, &res, &i);
126 ghostbyname_r (&buf, 0, 1024, &res, &i);
127 return 0;
128 }