]> git.ipfire.org Git - thirdparty/gcc.git/blob - libcc1/marshall.cc
Fix find_always_executed_bbs handling of infinite loops
[thirdparty/gcc.git] / libcc1 / marshall.cc
1 /* Marshalling and unmarshalling.
2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <cc1plugin-config.h>
21 #include <new>
22 #include <string.h>
23 #include "marshall.hh"
24 #include "connection.hh"
25 #include "rpc.hh"
26
27 cc1_plugin::status
28 cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
29 {
30 unsigned long long r;
31
32 if (!unmarshall (conn, &r))
33 return FAIL;
34 return check == r ? OK : FAIL;
35 }
36
37 cc1_plugin::status
38 cc1_plugin::marshall_intlike (connection *conn, unsigned long long val)
39 {
40 if (!conn->send ('i'))
41 return FAIL;
42 return conn->send (&val, sizeof (val));
43 }
44
45 cc1_plugin::status
46 cc1_plugin::unmarshall_intlike (connection *conn, unsigned long long *result)
47 {
48 if (!conn->require ('i'))
49 return FAIL;
50 return conn->get (result, sizeof (*result));
51 }
52
53 cc1_plugin::status
54 cc1_plugin::marshall (connection *conn, const char *str)
55 {
56 if (!conn->send ('s'))
57 return FAIL;
58
59 unsigned long long len = str == NULL ? -1ULL : strlen (str);
60 if (!conn->send (&len, sizeof (len)))
61 return FAIL;
62
63 if (str == NULL)
64 return OK;
65
66 return conn->send (str, len);
67 }
68
69 cc1_plugin::status
70 cc1_plugin::unmarshall (connection *conn, char **result)
71 {
72 unsigned long long len;
73
74 if (!conn->require ('s'))
75 return FAIL;
76 if (!conn->get (&len, sizeof (len)))
77 return FAIL;
78
79 if (len == -1ULL)
80 {
81 *result = NULL;
82 return OK;
83 }
84
85 char *str = new (std::nothrow) char[len + 1];
86 if (str == NULL)
87 return FAIL;
88
89 if (!conn->get (str, len))
90 {
91 delete[] str;
92 return FAIL;
93 }
94
95 str[len] = '\0';
96 *result = str;
97
98 return OK;
99 }
100
101 cc1_plugin::status
102 cc1_plugin::marshall_array_start (connection *conn, char id,
103 size_t n_elements)
104 {
105 if (!conn->send (id))
106 return FAIL;
107
108 unsigned long long r = n_elements;
109 if (!conn->send (&r, sizeof (r)))
110 return FAIL;
111
112 return OK;
113 }
114
115 cc1_plugin::status
116 cc1_plugin::marshall_array_elmts (connection *conn, size_t n_bytes,
117 void *elements)
118 {
119 return conn->send (elements, n_bytes);
120 }
121
122 cc1_plugin::status
123 cc1_plugin::unmarshall_array_start (connection *conn, char id,
124 size_t *n_elements)
125 {
126 unsigned long long len;
127
128 if (!conn->require (id))
129 return FAIL;
130 if (!conn->get (&len, sizeof (len)))
131 return FAIL;
132
133 *n_elements = len;
134
135 return OK;
136 }
137
138 cc1_plugin::status
139 cc1_plugin::unmarshall_array_elmts (connection *conn, size_t n_bytes,
140 void *elements)
141 {
142 return conn->get (elements, n_bytes);
143 }
144
145 cc1_plugin::status
146 cc1_plugin::marshall (connection *conn, const gcc_type_array *a)
147 {
148 size_t len;
149
150 if (a)
151 len = a->n_elements;
152 else
153 len = (size_t)-1;
154
155 if (!marshall_array_start (conn, 'a', len))
156 return FAIL;
157
158 if (!a)
159 return OK;
160
161 return marshall_array_elmts (conn, len * sizeof (a->elements[0]),
162 a->elements);
163 }
164
165 cc1_plugin::status
166 cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
167 {
168 size_t len;
169
170 if (!unmarshall_array_start (conn, 'a', &len))
171 return FAIL;
172
173 if (len == (size_t)-1)
174 {
175 *result = NULL;
176 return OK;
177 }
178
179 cc1_plugin::unique_ptr<gcc_type_array> gta (new gcc_type_array {});
180
181 gta->n_elements = len;
182 gta->elements = new gcc_type[len];
183
184 if (!unmarshall_array_elmts (conn,
185 len * sizeof (gta->elements[0]),
186 gta->elements))
187 return FAIL;
188
189 *result = gta.release ();
190
191 return OK;
192 }