|
|
1.1 root 1: /* Language-level data type conversion for GNU C.
2: Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
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: /* 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:
46: /* Subroutines of `convert'. */
47:
48: static tree
49: convert_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:
85: static tree
86: convert_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:
111: /* The result of this is always supposed to be a newly created tree node
112: not in use in any existing structure. */
113:
114: static tree
115: convert_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:
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:
364: tree
365: convert (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 archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.