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