]> gcc.gnu.org Git - gcc.git/blob - gcc/convert.c
(convert_to_integer): Delete Feb 19 change.
[gcc.git] / gcc / convert.c
1 /* Utility routines for data type conversion for GNU C.
2 Copyright (C) 1987, 1988, 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU C.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 /* These routines are somewhat language-independent utility function
22 intended to be called by the language-specific convert () functions. */
23
24 #include "config.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "convert.h"
28
29 /* Convert EXPR to some pointer type TYPE.
30
31 EXPR must be pointer, integer, enumeral, or literal zero;
32 in other cases error is called. */
33
34 tree
35 convert_to_pointer (type, expr)
36 tree type, expr;
37 {
38 register tree intype = TREE_TYPE (expr);
39 register enum tree_code form = TREE_CODE (intype);
40
41 if (integer_zerop (expr))
42 {
43 if (type == TREE_TYPE (null_pointer_node))
44 return null_pointer_node;
45 expr = build_int_2 (0, 0);
46 TREE_TYPE (expr) = type;
47 return expr;
48 }
49
50 if (form == POINTER_TYPE)
51 return build1 (NOP_EXPR, type, expr);
52
53
54 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
55 {
56 if (type_precision (intype) == POINTER_SIZE)
57 return build1 (CONVERT_EXPR, type, expr);
58 expr = convert (type_for_size (POINTER_SIZE, 0), expr);
59 if (TYPE_MODE (TREE_TYPE (expr)) != TYPE_MODE (type))
60 /* There is supposed to be some integral type
61 that is the same width as a pointer. */
62 abort ();
63 return convert_to_pointer (type, expr);
64 }
65
66 error ("cannot convert to a pointer type");
67
68 return null_pointer_node;
69 }
70
71 /* Convert EXPR to some floating-point type TYPE.
72
73 EXPR must be float, integer, or enumeral;
74 in other cases error is called. */
75
76 tree
77 convert_to_real (type, expr)
78 tree type, expr;
79 {
80 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
81
82 if (form == REAL_TYPE)
83 return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
84 type, expr);
85
86 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
87 return build1 (FLOAT_EXPR, type, expr);
88
89 if (form == POINTER_TYPE)
90 error ("pointer value used where a floating point value was expected");
91 else
92 error ("aggregate value used where a float was expected");
93
94 {
95 register tree tem = make_node (REAL_CST);
96 TREE_TYPE (tem) = type;
97 TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
98 return tem;
99 }
100 }
101
102 /* Convert EXPR to some integer (or enum) type TYPE.
103
104 EXPR must be pointer, integer, discrete (enum, char, or bool), or float;
105 in other cases error is called.
106
107 The result of this is always supposed to be a newly created tree node
108 not in use in any existing structure. */
109
110 tree
111 convert_to_integer (type, expr)
112 tree type, expr;
113 {
114 register tree intype = TREE_TYPE (expr);
115 register enum tree_code form = TREE_CODE (intype);
116
117 if (form == POINTER_TYPE)
118 {
119 if (integer_zerop (expr))
120 expr = integer_zero_node;
121 else
122 expr = fold (build1 (CONVERT_EXPR,
123 type_for_size (POINTER_SIZE, 0), expr));
124 intype = TREE_TYPE (expr);
125 form = TREE_CODE (intype);
126 if (intype == type)
127 return expr;
128 }
129
130 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE
131 || form == BOOLEAN_TYPE || form == CHAR_TYPE)
132 {
133 register unsigned outprec = TYPE_PRECISION (type);
134 register unsigned inprec = TYPE_PRECISION (intype);
135 register enum tree_code ex_form = TREE_CODE (expr);
136
137 /* If we are widening the type, put in an explicit conversion.
138 Similarly if we are not changing the width. However, if this is
139 a logical operation that just returns 0 or 1, we can change the
140 type of the expression (see below). */
141
142 if (TREE_CODE_CLASS (ex_form) == '<'
143 || ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
144 || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
145 || ex_form == TRUTH_XOR_EXPR || ex_form == TRUTH_NOT_EXPR)
146 {
147 TREE_TYPE (expr) = type;
148 return expr;
149 }
150 else if (outprec >= inprec)
151 return build1 (NOP_EXPR, type, expr);
152
153 /* Here detect when we can distribute the truncation down past some arithmetic.
154 For example, if adding two longs and converting to an int,
155 we can equally well convert both to ints and then add.
156 For the operations handled here, such truncation distribution
157 is always safe.
158 It is desirable in these cases:
159 1) when truncating down to full-word from a larger size
160 2) when truncating takes no work.
161 3) when at least one operand of the arithmetic has been extended
162 (as by C's default conversions). In this case we need two conversions
163 if we do the arithmetic as already requested, so we might as well
164 truncate both and then combine. Perhaps that way we need only one.
165
166 Note that in general we cannot do the arithmetic in a type
167 shorter than the desired result of conversion, even if the operands
168 are both extended from a shorter type, because they might overflow
169 if combined in that type. The exceptions to this--the times when
170 two narrow values can be combined in their narrow type even to
171 make a wider result--are handled by "shorten" in build_binary_op. */
172
173 switch (ex_form)
174 {
175 case RSHIFT_EXPR:
176 /* We can pass truncation down through right shifting
177 when the shift count is a nonpositive constant. */
178 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
179 && tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_one_node))
180 goto trunc1;
181 break;
182
183 case LSHIFT_EXPR:
184 /* We can pass truncation down through left shifting
185 when the shift count is a nonnegative constant. */
186 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
187 && ! tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_zero_node)
188 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
189 {
190 /* If shift count is less than the width of the truncated type,
191 really shift. */
192 if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
193 /* In this case, shifting is like multiplication. */
194 goto trunc1;
195 else
196 /* If it is >= that width, result is zero.
197 Handling this with trunc1 would give the wrong result:
198 (int) ((long long) a << 32) is well defined (as 0)
199 but (int) a << 32 is undefined and would get a warning. */
200 return convert_to_integer (type, integer_zero_node);
201 }
202 break;
203
204 case MAX_EXPR:
205 case MIN_EXPR:
206 case MULT_EXPR:
207 {
208 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
209 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
210
211 /* Don't distribute unless the output precision is at least as big
212 as the actual inputs. Otherwise, the comparison of the
213 truncated values will be wrong. */
214 if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
215 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
216 /* If signedness of arg0 and arg1 don't match,
217 we can't necessarily find a type to compare them in. */
218 && (TREE_UNSIGNED (TREE_TYPE (arg0))
219 == TREE_UNSIGNED (TREE_TYPE (arg1))))
220 goto trunc1;
221 break;
222 }
223
224 case PLUS_EXPR:
225 case MINUS_EXPR:
226 case BIT_AND_EXPR:
227 case BIT_IOR_EXPR:
228 case BIT_XOR_EXPR:
229 case BIT_ANDTC_EXPR:
230 trunc1:
231 {
232 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
233 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
234
235 if (outprec >= BITS_PER_WORD
236 || TRULY_NOOP_TRUNCATION (outprec, inprec)
237 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
238 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
239 {
240 /* Do the arithmetic in type TYPEX,
241 then convert result to TYPE. */
242 register tree typex = type;
243
244 /* Can't do arithmetic in enumeral types
245 so use an integer type that will hold the values. */
246 if (TREE_CODE (typex) == ENUMERAL_TYPE)
247 typex = type_for_size (TYPE_PRECISION (typex),
248 TREE_UNSIGNED (typex));
249
250 /* But now perhaps TYPEX is as wide as INPREC.
251 In that case, do nothing special here.
252 (Otherwise would recurse infinitely in convert. */
253 if (TYPE_PRECISION (typex) != inprec)
254 {
255 /* Don't do unsigned arithmetic where signed was wanted,
256 or vice versa.
257 Exception: if either of the original operands were
258 unsigned then can safely do the work as unsigned.
259 And we may need to do it as unsigned
260 if we truncate to the original size. */
261 typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
262 || TREE_UNSIGNED (TREE_TYPE (arg0))
263 || TREE_UNSIGNED (TREE_TYPE (arg1)))
264 ? unsigned_type (typex) : signed_type (typex));
265 return convert (type,
266 build_binary_op (ex_form,
267 convert (typex, arg0),
268 convert (typex, arg1),
269 0));
270 }
271 }
272 }
273 break;
274
275 case NEGATE_EXPR:
276 case BIT_NOT_EXPR:
277 case ABS_EXPR:
278 {
279 register tree typex = type;
280
281 /* Can't do arithmetic in enumeral types
282 so use an integer type that will hold the values. */
283 if (TREE_CODE (typex) == ENUMERAL_TYPE)
284 typex = type_for_size (TYPE_PRECISION (typex),
285 TREE_UNSIGNED (typex));
286
287 /* But now perhaps TYPEX is as wide as INPREC.
288 In that case, do nothing special here.
289 (Otherwise would recurse infinitely in convert. */
290 if (TYPE_PRECISION (typex) != inprec)
291 {
292 /* Don't do unsigned arithmetic where signed was wanted,
293 or vice versa. */
294 typex = (TREE_UNSIGNED (TREE_TYPE (expr))
295 ? unsigned_type (typex) : signed_type (typex));
296 return convert (type,
297 build_unary_op (ex_form,
298 convert (typex, TREE_OPERAND (expr, 0)),
299 1));
300 }
301 }
302
303 case NOP_EXPR:
304 /* If truncating after truncating, might as well do all at once.
305 If truncating after extending, we may get rid of wasted work. */
306 return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
307
308 case COND_EXPR:
309 /* Can treat the two alternative values like the operands
310 of an arithmetic expression. */
311 {
312 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
313 tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type);
314
315 if (outprec >= BITS_PER_WORD
316 || TRULY_NOOP_TRUNCATION (outprec, inprec)
317 || inprec > TYPE_PRECISION (TREE_TYPE (arg1))
318 || inprec > TYPE_PRECISION (TREE_TYPE (arg2)))
319 {
320 /* Do the arithmetic in type TYPEX,
321 then convert result to TYPE. */
322 register tree typex = type;
323
324 /* Can't do arithmetic in enumeral types
325 so use an integer type that will hold the values. */
326 if (TREE_CODE (typex) == ENUMERAL_TYPE)
327 typex = type_for_size (TYPE_PRECISION (typex),
328 TREE_UNSIGNED (typex));
329
330 /* But now perhaps TYPEX is as wide as INPREC.
331 In that case, do nothing special here.
332 (Otherwise would recurse infinitely in convert. */
333 if (TYPE_PRECISION (typex) != inprec)
334 {
335 /* Don't do unsigned arithmetic where signed was wanted,
336 or vice versa. */
337 typex = (TREE_UNSIGNED (TREE_TYPE (expr))
338 ? unsigned_type (typex) : signed_type (typex));
339 return convert (type,
340 fold (build (COND_EXPR, typex,
341 TREE_OPERAND (expr, 0),
342 convert (typex, arg1),
343 convert (typex, arg2))));
344 }
345 else
346 /* It is sometimes worthwhile
347 to push the narrowing down through the conditional. */
348 return fold (build (COND_EXPR, type,
349 TREE_OPERAND (expr, 0),
350 convert (type, TREE_OPERAND (expr, 1)),
351 convert (type, TREE_OPERAND (expr, 2))));
352 }
353 }
354
355 }
356
357 return build1 (NOP_EXPR, type, expr);
358 }
359
360 if (form == REAL_TYPE)
361 return build1 (FIX_TRUNC_EXPR, type, expr);
362
363 error ("aggregate value used where an integer was expected");
364
365 {
366 register tree tem = build_int_2 (0, 0);
367 TREE_TYPE (tem) = type;
368 return tem;
369 }
370 }
This page took 0.058047 seconds and 6 git commands to generate.